Button hell

Saturday, April 21st, 2007

If you want to style buttons in your web-application you inevitably end up with the <button> HTML element. There are alternatives: CSS’ing your <input type=submit> tag, using prerendered (!) images with <input type=image>, using links instead of form elements, etc. However if you want a flexible button layout without compromising the browser’s submit mechanics, then <button> should be the right thing, you’d think.
The “value proposition” goes like this: You can put any valid HTML inside the button element, for example background images or more spohisticated: a table with images for rounded corners on both sides and a stretching text-aligning middle AND it should behave like <input type=submit>. Nice! Ok and now to reality, welcome to “Button hell”.

  • <button> is broken in IE: And I mean it. Actually it is so broken that you’ll need hefty workarounds to get it working at all. Here’s why:
  • IE submits all button’s in your form: Yes! I mean what were they thinking? To clarify: You have three different buttons in your form, e.g. “save”, “delete” and “insert”. If you press one of them all corresponding values will be submitted! Which acutally means you can’t decide which button was clicked on the server side. One workaround would be to use hidden submit fields which are being filled by the button’s onclick handler.
  • IE button submits innerHTML: You might be tempted to believe that the “value” attribute holds the actual submit value. Actually this is what W3C says. Not in IE: In all circumstances the body of the <button> element will be submitted, that is: all your HTML code (escaped of course). If you submit via GET you will ultimately hit IE’s URI limit. This is a longstanding bug since IE5+ that eventually gets addressed in IE7.
  • IE stretches your buttons: Actually IE does this on all buttons not only those generated by the <button> tag. Why is this a problem? Well you use the button tag to style it according to your needs, which actually means you will disable the border of the original button and replace it with you images for example. However behind the scenes IE stretches the button proportionally to the enclosed text, only you can’t see the real dimensions any more! You will however see erratic paddings to your neighbour elements and wonder why the hell you cant right-align your buttons with your form. Thank god there’s a workaround.
  • Different paddings on browsers, Firefox nasty: Just as you think, you’ve everything under control, you open your form in another browser and start to scream again. See here for the details. Note the firefox behaviour:

    3px padding left and right, and 1px padding top and bottom appears to be added even when zero padding is applied. (Thus the user can never remove the padding completely. Buttons may also appear larger than expected.)

    Which acutally means you will not be able to right-align a image style button with your form in Firefox. It cost me hours to find out that the only workaround is to put the button content into a <div> or <table> and then apply negative 3px margins on that container.

  • You will need browser-specific CSS: As ugly it is, you will end up with conditionally included style-sheets to address the padding problems above…

Summing up the amount of work I needed to fight through the problems above, I would say it cost me a week of time and approx. 2500 hairs of my scalp.