Coding with Jesse

Using POST with a regular link

November 22nd, 2006

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!)

About the author

Jesse Skinner Hi, I'm Jesse Skinner. I'm a self-employed web developer with over two decades of experience. I love learning new things, finding ways to improve, and sharing what I've learned with others. I love to hear from my readers, so please get in touch!