Button hell

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.


15 Responses to “Button hell”

  1. Michiel Says:

    Test? (comment not posted?)

  2. Michiel Says:

    Hi Roman,

    Have a look at something I documented (and enhanced somewhat) at the link above.

    It addresses the first two of your problems. The other ones, I can usually work around by using CSS and a background image.

    Let me know if you have any questions/comments.

    Cheers,

    Michiel

  3. Roman Says:

    Hi michiel. Thanks for sharing!

    My workaround requires Javascript and changed markup i.e. surragate hidden fields for every button, the buttons themselves have no name and will therefore not be submitted, but their submit logic works anyway. I have no problem with changed markup because my html generation logic hides all those dirty details.

    Your solution works client/Javascript-only, which is great too. I tried something similar, but my problem was, that there can happen a lot between clicking a button and a form submit, for example javascript validation logic that is hooked up with the form submit handler. If submit fails you stay on the page and have disabled buttons all over the place. This is why my javascript code toggles hidden input fields only and not the buttons themselves.

    Roman

  4. pauldwaite Says:

    > you will end up with conditionally included style-sheets to address the padding problems above

    I end up with conditionally included stylesheets for all my sites as it’s my preferred way to work around IE bugs, but that thing with the value of every <button> being submitted, not just the one that received user input, sounds like a deal-breaker (unless none of a site’s forms will ever have multiple buttons).

  5. Internet Explorer y el elemento button - Scriptia Says:

    […] Tenía previsto escribir un artículo sobre el tema, pero otra vez se me han adelantado: con ustedes Button Hell, por Roman Radaschütz. […]

  6. El elemento button y Internet Explorer | aNieto2K Says:

    […] Hace unos días me preguntaba ¿por que se usaba <input /> en lugar de <button />? y desde entonces he recibido algunos motivos, entre ellos, y como era de esperar, Internet Explorer da problemas ya que submita todos los submits del formulario. […]

  7. Ric Says:

    Sorry but some of the reasons you list above are just stupid. If you are going to single [button] out as the bad guy then do so sensibly. For example, complaining that all [input]/[button] renders differently on different browsers is hardly a problem just for the [button] tag.

    Nope, sorry to say it but a very poorly written blog entry, imo, with no examples of the problems and an unclear agenda as to what exactly it is you are trying to prove.

    Regards,
    Ric.

  8. mahalie Says:

    Well, I found your post very informative, although examples would be even better. I found it via the Button solution on Particle Tree which I discovered resulted in a non-removable black line around the button after I implemented it. I wish I’d read your entry first. I must say though, for a form with only one button it seems like using the <button> tag would be okay (except for crappy IE7 rendering).

  9. GH Says:

    If you just add type=”button” to buttons it won’t submit the form in IE or firefox. By default, the button is created as type submit.
    You can also position the content of the button relatively (and negatively) to get around the problematic padding in Firefox rather than adding yet more elements.
    Suggest you do some more reading up on this area before jumping to conclusions.

  10. Idetrorce Says:

    very interesting, but I don’t agree with you
    Idetrorce

  11. Jarrod Says:

    Just curious about what fix there is for firefox and the extra padding issue? The button has the correct padding in ie6,ie7 and safari, but firefox adds about 3px extra.

    The main problem is that the design has some links and buttons looking the same, so the difference is obvious when put into HTML.

    If I add text-indent:-3px the other browsers will pick that up and display it wrongly. I just can’t think of an elegant solution for firefox (I am not going to add extra markup for every button)

    btw, I thought the article was pretty good

  12. TexTriptannep Says:

    I’d prefer reading in my native language, because my knowledge of your languange is no so well. But it was interesting! Look for some my links:

  13. jjanderson Says:

    I’d say the clear advantage of the BUTTON tag is that it allows you all the power of css.
    The problem that makes it useless is that in reality it is not supported in ie.
    Then you can apply your js-magic(tm) which could frankly be applied to most any other tag just as well and make javascript submit the form all together.

    So the beauty of the BUTTON tag is just wasted as you cannot design without catering to ie (at least not professionally)

    An alternative is the ‘input type=image’ which has some possibilities too.

  14. pike Says:

    Oh yay, I’m in button hell - its 02:00 at night, and i’ve been staring at it since .. 16:00. But anyway. I still prefer button above input, because it behaves *better* accross browsers, dd 2008/07

    as for mozillaas evil padding

    >3px padding left and right, and 1px padding top and bottom appears to be added
    >even when zero padding is applied.

    yes, very annoying. add this to your css
    button::-moz-focus-inner { padding:0; }

    and to underline a button in mozilla, use
    button { display:table-cell; text-decoration:underline; }

    ouch, very ugly. still looking for something better or at least moz-specific.

    *-pike

  15. pike Says:

    .. and found it

    click here

    @-moz-document url-prefix() { button.link { display:table-cell; text-decoration:underline }}

    yes, use the double {{ }}. oh boy !!!! that’s the ugliest -moz-hack I’ve seen sofar.

    *pike

Leave a Reply