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.
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:

Meh. Here’s the markup used when creating a button element that submits:
<button type="submit">Submit</button>
And it looks like this :

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 :

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.
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
- They had to look like buttons.
- They had to look the same across browsers.
- The styles I used for
buttonneeded 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).- The markup needed to be flexible and easy to change for uses in lots of different situations.
- 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 */
}
*:first-child+html button[type]{
padding:4px 10px 3px 7px; /* IE7 */
}
.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.
Change Password
Cancel