Coding with Jesse

Multiple IEs

This week, I installed TredoSoft's Multiple IE package (via friendly bit). It's an installer for Internet Explorer standalone versions 3, 4.01, 5.01, 5.5 and 6. It's based on evolt's standalone versions, but packed up in a nice installer. It even fixes some problems with cookies and conditional comments.

Check it out, it's a great package to have installed, and makes it a lot easier and cleaner to get all the old IEs running on your system. (You're all testing your web sites in IE 3, aren't you???)

Published on November 28th, 2006. © Jesse Skinner

Using POST with a regular link

Here's the problem: According to the principals of Representational State Transfer (REST), GET requests shouldn't change anything on the web server. Only POST requests should. For example, you really shouldn't have an <a> link that deletes an item. When you click a link, it sends a GET request to another page, and deleting an item is definitely a change. You should have a delete button that submits a form using POST instead.

Why? Well for one, Google Accelerator speeds up your web surfing by downloading all the pages that it knows about through the links on a page. So if there are links that delete items or other horrible things, Google Accelerator will go and delete everything for you. This actually happened to some users of 37 signals.

So the real solution is to just use a submit button for all the actions that actually do something (delete, save, etc.). And this is totally fine from a technical point of view, but not so great from an asthetic point of view. Buttons can be pretty ugly, right? (I actually like how they look, but then again, I'm not a designer.)

There is also another solution. You can use JavaScript to make a hidden form, then add an onclick event to a link that submits the form when you click the link. This solution is okay, except for those who don't have JavaScript (like search engine spiders).

I came up with a solution that tackles the problem from the asthetic angle. We can style the buttons so they look like links! Seriously!

Okay, it's not so easy. And it's not perfect. But it's pretty close. Here's the code:

.link-button {
    border: 0;
    padding: 0;
    background: inherit;
    font: inherit;

    cursor: pointer;
    text-decoration: underline;
    color: blue;

    overflow: visible;
}

<input type="submit" class="link-button" value="Delete"/>
<button type="submit" class="link-button">Delete</button>

It's a bit long because buttons have a lot of default styling to them. First, we remove the border, padding, background and font. Next, we change the mouse cursor and colour, and add an underline so that it looks and acts like a link. Last, we add this overflow: visible to force Internet Explorer to get rid of that weird spacing it adds inside buttons.

You might also have to set the actual font and size of the button to make it match the text around. I don't know why, but font: inherit just doesn't always do the job like it should. If you specifically set font: 12px Arial, it will look fine.

In Safari, it won't do anything if you're using an <input type="submit"> because you can't style these. However, you can style a <button type="submit"> though. You will just have to set the background colour directly and not use inherit. So as long as you don't have some trippy background image, it will be fine.

Another thing: it's not perfect in Firefox or Safari. It will still have some weird spacing around it. Have a look at what Firefox does:

Buttons have some spacing around them in Firefox

The top is a regular link, the bottom is a button. You can see it's pretty close, but not perfect. Safari has a similar effect with spacing on the bottom.

Well we can take it to the next level and use JavaScript so that it's perfect for the 90% of people who use JavaScript. The other 10% can see the extra spacing, but that's no big deal (they probably won't even notice). We can use the following function to accomplish this:

function replaceButtonWithLink(button) {
	var link = document.createElement('a');
	link.href = '#';

	// find link text either as value of input or innerHTML of button
	link.innerHTML = button.value || button.innerHTML;

	link.onclick = function() {
		button.form.submit();
		return false;
	};
	button.parentNode.insertBefore(link, button);
	button.parentNode.removeChild(button);
}

// here's what you do for an <input type="submit"/> or <button type="submit"/>
var button = document.getElementById("my_button");
replaceButtonWithLink(button);

Now we have a nearly perfect solution. If the spacing in Firefox isn't a problem for you, you don't even need the JavaScript portion. But it's there just in case you have some pixel-paranoid designers on your team that insist it should look perfect in their browsers (just hope they have JavaScript turned on!)

Published on November 22nd, 2006. © Jesse Skinner

Replace text with an image using CSS

Let's say you want to have a logo on a page, but you'd really like to use an <h1> with some text for the header in the HTML. Or maybe you like to use images for all your titles, but would still like to have plain text inside header tags in your HTML.

There are a number of reasons for wanting to do this, namely accessibility and search engine optimization. I talk more about this in my post Writing Semantic HTML.

The problem is: How do you hide the text? I think the most popular technique is to wrap the text with a <span> inside the header tag, then use some CSS to 1) hide the text, and 2) use the header tag as an image. Something like this:

<style type="text/css">
h1 {
    width: 500px;
    height: 100px;
    background: url(my_header_image.gif);
}

h1 span {
    display: none;
}
</style>

<h1><span>My Great Header</span></h1>

Unfortunately, this technique makes us add an extra tag to our markup, and we all know that every time we use an unnecessary tag, a puppy dies. Either that, or we end up with ugly, unnecessarily bloated HTML.

Well here's another technique which hides the text just by using CSS. The text will still be readable by screenreaders and search engine spiders, but will disappear like magic for everyone else:

<style type="text/css">
h1 {
    width: 500px;
    height: 100px;
    background: url(my_header_image.gif);
    overflow: hidden;
    line-height: 500px;
}
</style>

<h1>My Great Header</h1>

This technique works by pushing the text down inside the header with a rather large line-height (it must be at least twice the height). Then the overflow: hidden hides the text since it's overflowing.

Now isn't that better? No puppies were harmed, and we end up with slightly cleaner and shorter markup.

Published on November 7th, 2006. © Jesse Skinner

The Ajax Experience Wrap-up

I had a really great time at The Ajax Experience, and got to meet a lot of really cool fellow JavaScript hackers. The sessions were all very interesting, but what really stuck with me was the difference that a good JavaScript library can really make in your development.

John Resig's talk on Choosing a JavaScript Library showed how much cleaner and faster development can be when a library offers elegant solutions to very common problems. And I assume John used some kind of Jedi mind trick because his talk made me choose his own library, jQuery. I even rewrote my talk's examples in jQuery to make them shorter. I'm sure I'll be writing a lot about jQuery on here in the future.

My "Unobtrusive Ajax" talk went pretty well, I thought. I realised afterwards that I hadn't pointed people at my examples for download. So if you attended and want to take a second look, or if you didn't attend but still want to see what it was all about, go check out the downloads below:

And please, contact me if you have any questions or comments about any of this stuff.

Published on October 26th, 2006. © Jesse Skinner

Carnival of the Web is on hiatus

Unfortunately, there will be no Carnival of the Web this month. I'll be putting it on hiatus indefinitely. Now that I'm freelancing, I simply don't have the time to read through blogs and pick the best posts. Perhaps it will come back some time in the future. I apologize to everyone who had submitted articles for the fifth edition.

Published on October 21st, 2006. © Jesse Skinner
<< older posts newer posts >> All posts

Contact Jesse

Need help with a project? Any questions about my writing? I'd love to hear from you.

Email me at [email protected]