Archive for January, 2010

Another new theme

2010-01-26 – 10:25am

I was never really happy with my previous 2010 theme, so I’ve gone and done a completely new one.

This new one makes extensive use of CSS3 properties, such as gradients and shadows. It looks best in Firefox >= 3.6,followed by Safari >= 4, then Chrome >= 4, Opera >= 10, and IE >= 8. Theoretically, Firefox and Safari/Chrome support the same level of features, but the webkit gradient syntax is absolutely awful. It’s confusing, needlessly complex, and poorly thought-out, in my opinion. Contrast the following two lines:

background: -moz-linear-gradient(top, #111, #333);
background: -webkit-gradient(linear, left top, left bottom, from(#222), to(#333));

See what I mean?

Gecko (Firefox), Webkit (Safari), and Trident (IE) rendering.

Clean Word markup

2010-01-20 – 12:21pm

When writing a web-app that accepts formatted input from users, you’ll often find that they will copy and paste text from Microsoft Word. Unfortunately, Word fills the markup with lots of unnecessary and unwanted muck. To clean this all up, I wrote the following function (directly implemented on the String prototype below):

String.implement({
	sanitiseWord: function() {
		var s = this.replace(/\r/g, '\n').replace(/\n/g, ' ');
		var rs = [];
		rs.push(/<!--.+?-->/g); // Comments
		rs.push(/<title>.+?<\/title>/g); // Title
		rs.push(/<(meta|link|.?o:|.?style|.?div|.?head|.?html|body|.?body|.?span|!\[)[^>]*?>/g); // Unnecessary tags
		rs.push(/ v:.*?=".*?"/g); // Weird nonsense attributes
		rs.push(/ style=".*?"/g); // Styles
		rs.push(/ class=".*?"/g); // Classes
		rs.push(/(&nbsp;){2,}/g); // Redundant &nbsp;s
		rs.push(/<p>(\s|&nbsp;)*?<\/p>/g); // Empty paragraphs
		rs.each(function(regex) {
			s = s.replace(regex, '');
		});
		return s.replace(/\s+/g, ' ');
	}
});

If you’re not using MooTools, the function will look something like this:

String.prototype.sanitiseWord = function() {
// function body here...
};

Usage

var s = "(some awful Word markup)".sanitiseWord();

In one of the tests I ran, the input went from around 7000 characters to just 700.

Example

Some of the regular expressions I used were adapted from C# ones in a post by Jeff Atwood.

The problem

When styling text <input> elements, it’s fairly common to run into a serious problem: they don’t behave like block-level elements.

Note: In all of the examples, the container element is filled with blue, and the <input> itself is filled with red and has an opacity of 50% so that you can see it under- or over-flowing the container.

<div  style="background: blue; width:200px;">
  <input  style="display:block; padding:4px; background: red; opacity:0.5; border:0;" type="text" value="text input"/>
</div>

You can see how the input doesn’t automatically flow to full width, as the “display: block” style suggests it should. The kneejerk response is to set the width to 100%:

<div  style="background: blue; width:200px;">
  <input  style="display:block; padding:4px; background: red; opacity:0.5; width:100%; border:0;" type="text" value="text input"/>
</div>

But notice now how the input overflows its container’s boundaries because of the left padding. At this point, people may resort to non-semantic markup (removing the padding on the <input> and putting it inside a padded <div>) or JavaScript solutions that set the pixel width whenever the container’s width changes (by the addition of scrollbars, for example).

The (semantic) solution

But wait! There is a way to achieve this effect without resorting to an extra <div> or JavaScript:

<div  style="background: blue; width:200px;">
  <input  style="display:block; padding:4px 0; background: red; opacity:0.5; width:100%; border:0; text-indent:4px;" type="text" value="text input"/>
</div>

Do you see what I did there? I removed the horizontal padding on the <input>, so the 100% width now works correctly, and replaced it with “text-indent”. To the user, this looks no different, and it has the advantage of requiring no extraneous markup or tedious scripting.

Drawbacks

  1. Should the user enter a long string, their text will bump up against the right edge. But I think that that’s a boundary condition that I can live with.
  2. Any vertical borders on the <input> will cause it to overflow its container. Personally, if I want a full-width <input>, though, I generally don’t want any borders on its left or right other than those of its container.