Anyone who's used the web has encountered buttons in forms. Buttons, as with most form controls, can be a bit tricky to style for consistent look cross browser and cross platform as the operating system often has more to do with how they are rendered than the browser itself. Roger Johansson has delved into this issue in more detail.
What I'm going to do here is present a few different options available for styling your buttons.
There's two ways to add a button to your HTML: using either the
input tag or the
buttontag. The most commonly used is probably the
input although I think, and will show here, how the
buttoncan be more flexible.
First, let's look at the two options sans-styling:
In most OSes, when you roll over the buttons, there will be a slight colour change, but what else can be done to make them stand out?
I’m going to be using inline styles to illustrate some examples, but ordinarily all these styles would be moved to your stylesheet.
These styles will also apply equally well to both inputs and buttons. If you’ve applied styles to other inputs on your page, you’re going to need some mechanism to override these styles for your input buttons. For browsers, other than Internet Explorer, we can use
Changing button colour
We can change the colour of the button’s text and we can make it bold too:
Making the text bigger
We can, of course, also make the text size much bigger and we could also uppercase the text:
We can also change which font is used and the
letter-spacing of the text.
Changing the background
All the changes suggested so far deal only with the text and not the background of the button itself. We can change a button’s background or border too, but when this happens, the button will lose its 3D look and become a solid rectangle.
In his article on styling form widgets, the Man in Blue, Cameron Adams warns against styling buttons in this way and taking away the user’s ‘perceived affordance’ so they
will not recognise how they interact with an element, or take longer to do so. It’s certainly a valid point, but a couple of years later, I think web users are more used to different types of buttons and this may not be such a problem as it was.
But to make sure your users understand the button is in fact a button and not just another form input (or any other rectangle on the page), there’s a few things we can do.
In the unstyled example, the button’s background changed colour slightly on rollover. We can do the same thing here:
We could also change the cursor to a hand to make it look more like something that should be pressed:
As noted in the Man in Blue example above, we can give the button a double-edged border:
So far, we’ve just used a solid
background-color for the buttons, but we can use
background-images just the same.
Adding images to buttons
So far, we’ve changed the button’s text and background, but we can also add some imagery to the button. Except we can’t use an
input; this is where another of the
button‘s advantages comes into play. Unlike inputs which are inline-replaced elements, buttons can contain other content which can include images.
IE adds extra space to the left and right of the content when an image is placed in the button so I’ve used the Holly Hack to give it a width.
Replacing buttons with images
Now, what if we wanted to go a step further and replace the whole button with an image so that we can give it a different shape or use a particular font of our choosing? The most straightforward way to do this is to use an
type set to
Note the use of the
alt attribute to describe what the input does. This is important for people who browse with images off because otherwise they wouldn’t see the button.
This looks like a button but doesn’t have a rollover effect like a non-styled button or the examples we’ve just been looking at. You’ll notice the name of the image is
submit-button-off.gif and that’s because there is also a
We could attach the
The script below is based on one by Christian Watson but I’ve trimmed it back because I’m not targetting all images and not supporting older browsers.
The script finds all inputs on the page and then determines if they’re of
type=image. It then uses the image’s src to create the variables for both on and off states by simply replacing off with on in the image name. Then it’s just a matter of applying the correct state
onblur are for keyboard users. (Safari also has a problem with onload for off-screen images which is why the conditional statement sets up a different set of functions for it.) Which gives us this (HTML is same as the previous example):
Using CSS image replacement
button comes into play again. As the
button can contain other content, we can use an image replacement technique on it. My preferred method is the Gilder Levin Ryznar Jacoubsen IR technique which I’ve used on my article on combining image replacement with Suckerfish dropdowns.
There’s one notable difference between this and the Gilder Levin Ryznar Jacoubsen method and that’s that the
background-image isn’t attached to the parent element, the button, as well. To do so causes the rear image to be visible by a few pixels behind the front image.
float: left and
display: inline on the
button itself are also required by Opera 8 & 9 to ensure that they render the image at all (v9) and in the right place (v8) (thanks to Paul O’Brien for the tip).
The actual image for the button contains both on and off states and looks like this:
Using the button’s
background-position property we can move the off state out of view and replace it with the on state when the image is hovered over (see above for the extra help that IE needs on this). With images turned off, the user will still see the button’s text making this a better option than image replacement methods that move the text off-screen.
So we can use images that look like buttons but still have our own style about them at the same time as retaining the user interaction element by enabling change of state when the mouse is hovered over the button or it is tabbed into using the keyboard.
Mon, Feb 18, 2008 @ 9:41 am
I’ve begun using JQuery on this site recently and as such have replaced the script above with this: