Introduction

Creating a consistent interface for your users is a constant struggle for every application designer. Building consistency on the web is especially tough because the visual rendering differences across browsers and operating systems are wildly different and almost arbitrary in what can and cannot be done. No where does this become more apparent than when you’re dealing with form elements and the biggest loser of them all in the battle for a standardized look is the infamous Submit button.

HTML Form Builder

As is, the input with the type=”submit” is either too ugly (Firefox), a little buggy (Internet Explorer) or completely inflexible (Safari). The solution for most is to use image inputs and create the damn things ourselves. And it’s unfortunate, because then we’re reduced to the tedious tasks of opening up Photoshop every time we’re in need of a new button. What we need is something better—something more flexible and meant for designers. Lucky for us, the solution already exists and all it needs is a little love. My friends, let me introduce you to my little friend : the <button> element.

Inputs vs Buttons

So, here’s your standard submit button markup:

<input type="submit" value="Submit" />

And it looks like this across the three brothers:

Input Submits

Meh. Here’s the markup used when creating a button element that submits:

<button type="submit">Submit</button>

And it looks like this :

Buttons

These buttons work and behave in exactly the same way as our counterparts above. In addition to submitting the form, you can make them disabled, add an accesskey or even specify a tabindex. Aside from the visual indifference Safari seems to have for them (it doesn’t put that forced aqua interface on it, which we’ll be able to use to our advantage), the coolest thing about the <button> tag is that you can put useful HTML elements inside them, like images:

<button type="submit"><img src="" alt="" /> Submit</button>

Which looks like this :

Buttons with Images

Nice. (Okay, they’re a little fugly, but I said they’re in need of a little love.) In fact, according to the W3C these special visual differences is exactly why the <button> elements were created.

Buttons created with the BUTTON element function just like buttons created with the INPUT element, but they offer richer rendering possibilities: the BUTTON element may have content. For example, a BUTTON element that contains an image functions like and may resemble an INPUT element whose type is set to “image”, but the BUTTON element type allows content.

The Button Element - W3C

And so here we were looking for a design solution and here our friends writing the giant handbook of the Internet had a piece of markup meant to help us with just such a problem. Convenient, yet unfortunate that most designers and developers don’t even know the element exists. Now, before I made the jump to replace all the image inputs in Wufoo with button elements, I decided that the markup and CSS would have to fulfill a couple of requirements.

The Requirements

  1. They had to look like buttons.

  2. They had to look the same across browsers.

  3. The styles I used for button needed to also be used with ones I might use with links (since interaction in Wufoo is always initiated with either a Form Submission or an Ajax Call from a link, these things probably sit next to each other and I needed them to have the same visual weight).

  4. The markup needed to be flexible and easy to change for uses in lots of different situations.

  5. I should be able to use icons and colors effectively to pass information about the kind of interaction that would be taking place.

With those challenges in place, I dove into the CSS and after solving some cross browser challenges, came up with the following (which you can also see all over Wufoo):

The Results


Nothing crazy. Simple, but effective. Now, what I love about this way of handling buttons is that I can use the 1000 icon arsenal from FAMFAMFAM to illustrate a ridiculous number of ideas and actions without having to generate something from Photoshop every single time I need something new. If we take a quick look at the markup, you’ll notice that the last two buttons up there are actually links:

<div class="buttons">
    <button type="submit" class="positive">
        <img src="/images/icons/tick.png" alt=""/> 
        Save
    </button>

    <a href="/password/reset/">
        <img src="/images/icons/textfield_key.png" alt=""/> 
        Change Password
    </a>

    <a href="#" class="negative">
        <img src="/images/icons/cross.png" alt=""/>
        Cancel
    </a>
</div>

The reason this is useful is because lots of actions in web applications are REST driven and so simply sending a user via a link to a specific URL will initiate something they need to do. Using styles that can work for both types of elements (links and buttons), gives us the flexibility to keep our means of interaction looking consistent and appropriate whether it’s being done with Ajax or a standard submission.

Just a quick aside, you may wonder why I’ve left the alt tags blank in those icon images. It may come as a surprise to some that while alt attributes are required on every image, actually describing them is not. Empty alt attributes are completely valid and help screenreaders know which information to effectively ignore, saving your users precious time when they’re trying to find the next appropriate actionable item. Because the icons are actually superfluous, I’d rather not waste the user’s time hearing about the image I used to visualize what’s going on. They’ll just hear “Submit” rather than “Checkmark Submit”, which would actually make things a little confusing.

The CSS

For the most part, the CSS for styling these buttons are fairly straight forward. The hair-pulling inconsistencies across browsers results in the number of padding discrepancies below, but it’s nothing impossible and lucky for you, already figured out.

/* BUTTONS */

.buttons a, .buttons button{
    display:block;
    float:left;
    margin:0 7px 0 0;
    background-color:#f5f5f5;
    border:1px solid #dedede;
    border-top:1px solid #eee;
    border-left:1px solid #eee;

    font-family:"Lucida Grande", Tahoma, Arial, Verdana, sans-serif;
    font-size:100%;
    line-height:130%;
    text-decoration:none;
    font-weight:bold;
    color:#565656;
    cursor:pointer;
    padding:5px 10px 6px 7px; /* Links */
}
.buttons button{
    width:auto;
    overflow:visible;
    padding:4px 10px 3px 7px; /* IE6 */
}
.buttons button[type]{
    padding:5px 10px 5px 7px; /* Firefox */
    line-height:17px; /* Safari */
}
.buttons button img, .buttons a img{
    margin:0 3px -3px 0 !important;
    padding:0;
    border:none;
    width:16px;
    height:16px;
}

One thing that came up while working on this was the fact that there’s a rendering bug in Internet Explorer in regards to showing long buttons. You can read about it at Jehiah.cz, but it’s what’s responsible for some of the width and overflow declarations above.

Adding Some Color

In Wufoo, we made the hover color blue for neutral actions and used green and red appropriately for positive and negative connotations. The following are the styles we’ve created for dealing with buttons that are meant to show positive interactions like adding and saving and negative interactions like canceling and deleting. It’s a nice touch for us and obviously you can pick and choose to your liking.

/* STANDARD */

button:hover, .buttons a:hover{
    background-color:#dff4ff;
    border:1px solid #c2e1ef;
    color:#336699;
}
.buttons a:active{
    background-color:#6299c5;
    border:1px solid #6299c5;
    color:#fff;
}

/* POSITIVE */

button.positive, .buttons a.positive{
    color:#529214;
}
.buttons a.positive:hover, button.positive:hover{
    background-color:#E6EFC2;
    border:1px solid #C6D880;
    color:#529214;
}
.buttons a.positive:active{
    background-color:#529214;
    border:1px solid #529214;
    color:#fff;
}

/* NEGATIVE */

.buttons a.negative, button.negative{
    color:#d12f19;
}
.buttons a.negative:hover, button.negative:hover{
    background:#fbe3e4;
    border:1px solid #fbc2c4;
    color:#d12f19;
}
.buttons a.negative:active{
    background-color:#d12f19;
    border:1px solid #d12f19;
    color:#fff;
}

Conclusion

In the end, this is just how we’ve decided to handle things with Wufoo and it’s worked out wonderfully for us in regards to our development workflow. Of course, this isn’t the only way to play the game. There’s lots of ways you can spice this up (use gradients!) and change things around (use image replacements over images in the markup). Because the <button> tag can handle nearly any kind of markup inside there, you can add some <span> tags and use Alex Griffioen’s recently written method on creating really beautiful rounded gradient creations. Honestly, I’m hoping this is just a great starting point for a lot of designers struggling with reusable form interfaces in their applications. If anything, I hope you take another look at this often wasted form element and think twice before reaching for that input and PSD for submission.

Kevin Hale

Rediscovering the Button Element by Kevin Hale

This entry was posted Yesterday and was filed under Features.
You can follow comments on this entry by subscribing to the RSS feed.

· 60 Comments! ·

  1. Joseph R. B. Taylor · 22 hours ago

    Great write up on the button. I’m switching right now!

  2. dagobert renouf · 22 hours ago

    good post !

    great technique !

  3. Paul Hart · 21 hours ago

    Beautiful stuff, I’ll be stealing that technique for something I’m working on at the moment.

  4. Rob B · 21 hours ago

    I believe there is a small issue for using the button tag in IE: if you count on the value being passed along when a button is clicked to determine an action (e.g., save v. change password v. cancel in the example above), you may be up a creek: http://www.peterbe.com/plog/button-tag-in-IE

    Maybe there is a better way to handle multiple buttons, but I actually look for the name of the button that was selected in the POST data. It will work fine if you only have one button (or, I guess, many buttons that do the same thing, as in one application I saw once :)).

  5. Kevin Hale · 21 hours ago

    Hey Rob, I do remember reading that while doing the research on this. Honestly, it’s a non issue for us because there’s only ever one button that submits a form on our web application. The other buttons are always links and so that’s the method we use.

    It’s hard, also, for me to come up with multiple reasons why you might need multiple button inputs on a form. If anyone could provide some useful examples, I’d much appreciate it.

  6. Cory · 21 hours ago

    Yeah, this IE issue was a huge pain in the butt for me once. I discovered that buttons were easier to style using this technique over a year ago, recommended it to my boss, and then implemented them in a web application. When our client couldn’t get it to work on IE, it took quite a while to figure out the bug. I’ve never used them again since, but perhaps there is a better way to handle multiple button actions.

  7. Phil Kast · 21 hours ago

    Great article about an element I always forget. Thanks!

  8. Edward · 20 hours ago

    I like how you guys put the code in black!

  9. Carlos Eduardo · 20 hours ago

    Since I’ve been using this tag, my forms can look smarter, ‘cause I can use “text-indent” to doesn’t display text inside buttons, using a image on background for it.

    On IE it works only with button tag.

  10. Ben Eastaugh · 20 hours ago

    You chaps are true heroes of the interwebs.

  11. Mislav · 19 hours ago

    No where does this become more apparent than when you’re dealing with form elements and the biggest loser of them all in the battle for a standardized look is the infamous Submit button.

    In my opinion, the biggest loser of them all is the infamous file input button.

    PS. I never noticed it before, but here it goes: are you guys aware that the label for comment textbox says You may use HTML for style?

  12. Francis Wu · 19 hours ago

    Kevin, one example of multiple buttons is one that I get from numerous clients: OK and Cancel. Personally, I understand the one-button-plus-links convention, but my clients aren’t exactly fond of this for two reasons: it doesn’t look nice and they’re used to the conventions of desktop software.

  13. Francis Wu · 19 hours ago

    Mislav — Ah yes, the dreaded file input field! Just the mere mention of it makes my blood boil! Grrr!!!

  14. Jon B · 19 hours ago

    Just wanted to point out that there are issues with this - in IE7 save button active states don’t work, the button is taller than the links, and it has a black border all round it.

    In firefox 2 the save button is slightly taller than the links.

    I’m using Vista.

  15. Kevin Hale · 19 hours ago

    Francis, this is why we implement the styles in a way that makes them look identical. We use Save and Cancel all the time in mixed button/link format and the stylings shown here keep them from looking awful.

  16. Francis Wu · 19 hours ago

    Kevin, I like this approach! Any way to get around the weird solid border around the button in IE6 though — besides upgrading :P?

  17. Steve · 18 hours ago

    As mentioned by a few, the button element is the coolest ever!, and the worst implemented on IE.

    Issues:
    1.) IE submits the .innerHTML as the value, not the value attribute
    2.) If you put an animated GIF, as your image, IE doesn’t render the transparency properly, at all… turns the face of the button white
    3.) If you want the button to do something, but not submit, you need to play some games (Firefox vs. IE)
    4.) They render horribly in IE, if the text is long, and you haven’t hacked your CSS to accomodate
    5.) Any “button” elements not clicked, are not submitted as part of the form (just something to keep in mind)
    6.) IE handles the default padding/margin differently, for input vs. button when hover/click events occur (need to tweak CSS)
    7.) Generating button elements in IE, via DOM calls can cause issues (rare, but be warned)

    Also I’m not sure if this is relevant (haven’t tested), but Auto-Complete in IE (the storage of previously typed data), does not work with input:type=button fileds, it has to be input:type=submit. I would hope that the button element behaves the same as the submit, but if it doesn’t, then auto-completion will be broken. (need to test, to verify this)

  18. Steve · 18 hours ago

    Addition… the button element does store the values for auto-complete in IE (good news)

    Now if only they would fix the someForm.submit(); to work ;-)

  19. Ed Eliot · 16 hours ago

    A nicely written article. I think the only point I’d add is that it would be better if you made the icons background images to the button and anchor elements and applied with a suitable class (which you already have in two cases anyway). That way you’re not adding additional markup for what is essentially a presentational effect.

  20. Nathan Saritschniy · 15 hours ago

    In my experience in building XHTML/CSS UI for developers that they have major issues when they use the element in IE as others have. Therefore, I have resorted to wrapping buttons in a

    <

    div>, which should allow enough of a hook to re-create the same styling effects demonstrated here.

  21. Diego · 13 hours ago

    looks great in firefox 2, but save buttom are not working in IE6 ( border , and hover properties)

  22. thespy · 12 hours ago

    Uhhh, even though I’m a Firefox user, what about adding Opera to that review, I’m sure there’s still a lot of people that browse the web with it!

  23. Peter · 12 hours ago

    Everyone needs a hug.

  24. Salman · 12 hours ago

    The top half is cut off in Opera (until you hover over them).

    Not to be harsh, but whenever i see a cross-browser CSS guide of any kind, and it doesn’t work in Opera… I get sad. Why does everyone ignore us Opera users? =P

  25. James · 11 hours ago

    Salman, which version of Opera are you using, it looks fine in 9.20. I agree it’s difficult to create a CSS that suits every browser. And Opera is always different from the rest.

    Anyway, great write-up.

  26. tester-du · 11 hours ago

    Testing…du

  27. The Pandora Effect · 11 hours ago

    THIS SITE IS REALLY GOOD. useful in a thousand ways. haha. thx for the art.

    Pandora E.

  28. james · 11 hours ago

    By far the coolest looking comment section i’ve ever seen

  29. John Schuster · 11 hours ago

    Everyone needs a hug.
    Hey thanks for the code demo.
    This is a very useful piece of info.

  30. chris · 11 hours ago

    Could you not do the exact same thing by setting a class with the required styles?

    .save {

    }

    The reason that I ask is that a lot of frameworks render out something out of your control, ex ROR, ASP.NET, so the ability to use the button element isn’t there.

  31. Kris · 11 hours ago

    Why fake it, when you can just deploy a Java Swing application with webstart? There is even a plugin in Maven 2 that makes the whole process trivial.

    One JNLP url = escape from browser incompatibility hell.

    BTW, Love your “Submit Comment” button ;)

  32. Market Matador · 11 hours ago

    Never even knew that a button could be customized so heavily! Cool write-up man!

  33. ayeroxor · 10 hours ago

    Nice work!

    oh, and, uh, Everyone needs a hug…

  34. CodeBit.cn · 10 hours ago

    very good !
    thanks !

  35. jaySeattle · 10 hours ago

    I guess I’d be the one critic of this technically sound feat in saying “Why”? What are you giving the user with the addition of an icon in a button control? Of the three, Save, Change Password, and Cancel, the Cancel extra emphasis seems possibly helpful though I would imagine OK/Cancel is well understood by letting the OS render the control & state. Change password graphic is ambiguous. Save graphic is not helpful visually in the least.

    Not a fan of MSFT, but I’d side with them on the usability/reasoning on this technique:
    http://msdn2.microsoft.com/en-us/library/aa511453.aspx
    “Avoid combining text labels and graphics on command buttons. Combining text and graphics usually adds unnecessary visual clutter and does not improve the user’s comprehension. Consider combining text and graphics only when the graphic aids in comprehension, such as when it is a standard symbol for the command or it helps users visualize the results of the command. Otherwise, prefer text, but use either text or graphics.”

  36. Andrew · 9 hours ago

    Great work, will definitely be using this in the future.

  37. Deaf Musician · 9 hours ago

    Great article. I’ve reading this site for 6-7 months now. Did you guys stop writing the e-book / e-articles? Get them going again! Great stuff, once again.

  38. John · 7 hours ago

    The end here is excellent and I love the way the buttons come out visually.
    Say what you will about useless icons consfusing users etc etc… in almost every real world case I find that, when standardized in an application, icons + text serve as a visial reinforcement to the user which ends up helping them use the application more quickly and accurately.

    With that said, the way IE handles the button element is outlandish. Especially when you’re talking about returned variables. This has caused more ambiguous bug hunting than I care to remember.

    I don’t discourage using the button element but make SURE you familiarize yourself with how IE will toss your variables to you. If you can’t make the button “name” and “value” attributes identical (there might be a number of good reasons why you wouldn’t?) then your backend code may actually have to handle multiple cases depending on the browser… that gets uselessly dirty.

  39. Nick van der Linde · 7 hours ago

    Thanks for reminding us of this long forgotten element. I agree with Ed Eliot though on the fact that you’d better include the icons in your stylesheet rather than using images. It makes your markup look less cluttered.

  40. Neon · 6 hours ago

    Great article, more interested in the great way that you display your comments. When it comes down to it, the whole site is really nice. Great job :)

  41. Sam · 6 hours ago

    This is the worst layout for a “comments” section that I have ever seen. Why, since we’re talking about usability, are there two columns?!

  42. Mike · 6 hours ago

    Why not mention more of the downsides in the article?

    PS> Very confusing to see the comments in this layout. I much prefer just one column ordered by date

  43. Angga · 6 hours ago

    Genius ! never knew that button can be used that way. I’m switching now.
    Thanks for the information

  44. Tom · 6 hours ago

    This is great, thanks a million for the article. I have been writing a ASP application for work and have been trying to implement some sort of buttons, but have been stuck with the boring original styled ones, now I can use great hover effects and standardise the look and feel.

  45. David Horn · 6 hours ago

    Fantastic - thanks for the great write up!

  46. pitsam · 6 hours ago

    Absolutely adoreable!

  47. Michiel · 5 hours ago

    Nice article. I recently ran into some problems using multiple buttons for form submission in Internet Explorer (6). I combined some tips from other sources into a solution which works nicely. I put some info on this up at:
    http://www.kopz.org/public/documents/css/multiple_buttons_ie_workaround.html
    Hope this is useful for anyone running into the same problem.

  48. Kilian Valkhof · 5 hours ago

    Finally an article on the <button> element, IMO one of the most overlooked html element. It is far easier to style and behaves exactly as you’d expect it too (heh, as a button).

    I wasn’t aware of the problems with IE, haven’t ran unto the problem yet. Keeping the value the same as the inner value probably “solves” that.

    Good article, and a classy solution on the Wufoo buttons! :)

  49. Mindloop Webdesign · 5 hours ago

    Great article,
    I’ve been using a similar technique to style buttons and links alike.

    But I would advise on setting the images in your stylesheet as background-image instead of wrapping them in the a and button tags.

  50. Portal · 5 hours ago

    simple and straight to the point

  51. Ian · 4 hours ago

    Great - thanks for the guide.

  52. Niranjan Deshmukh · 4 hours ago

    Everyone needs a hug.
    Great write up!

  53. Alex · 3 hours ago

    Great article, always learning something new ;)

  54. Josiah Pugh · 2 hours ago

    I really dig your comment style.

  55. Motorcycle Guy · 2 hours ago

    This is a great article, I’ve never actually used a button instead of input.

  56. Pensador · 2 hours ago

    I really liked the “The Results”! I shall use them on my personal blog!

  57. Stuart · 1 hour ago

    Great article as always Kevin. I’ll agree with a few other commenters though, your comment layout gives me a headache. Blehhch….

  58. Brandan · 59 minutes ago

    You’ve gotten a lot of praise on this, so I’m going to criticize :-)

    The button element does afford you consistency across browsers, but is cross-browser visual consistency really that important for a form submit? How many people are using multiple browsers per session to view a site and would benefit from that consistency?

    I’ll argue that it’s more important that a button on a web page look like a button in a rich-client app in my OS. The reason Safari uses Aqua styling of submit input elements is because almost every other button in OS X does too. So the “Gather Windows” button in my Display preferences looks exactly like your “Submit Comment” button at the bottom of this page, and I can safely expect similar behavior from both of them. I can’t speak for Windows/IE on that topic.

  59. Dan Boland · 26 minutes ago

    Great article — this is something I’ll definitely look into utilizing from now on.

    However, it doesn’t seem to adhere to any Javascript that’s attached to it, unlike the tried and true input button. So unless someone can steer me in the right direction with that regard, I’ll just stick to applying to more “traditional” forms.

  60. MonkeyMan · Right Now

    I’ve done this on a few occasions in the past, but had totally forgotten about it. Thanks for the refresher!