I’ve been writing recently about making user interface elements with new CSS features, but that’s not always your best option. If you’d like to customize your interface and still support old browsers, you should take a look at Uniform. Uniform replaces your real form elements on-the-fly using jQuery.

One of the major differences between Uniform and the methods outlined in my recent posts is that Uniform uses images from a theme. Personally, I am rather fond of the Agent theme.
I’ve gotten some good feedback about my previous CSS tutorial, Sexy CSS Buttons, so I figured I would make a series of tutorials on creating a sexy user interface for Web applications using nothing but the power of CSS. This installment will teach you how to create a sexy toolbar, like so:

We are going to start by creating an unordered list using the HTML element <ul> and give it the classname toolbar. This will simplify the markup needed and will be fairly easy to decorate with CSS.
<ul class=”toolbar”>
<li>This</li>
<li>is</li>
<li>our</li>
<li>toolbar</li>
</ul>
Now we need to style the list. Most importantly, we need to set list-style-type to none to remove the bullets. Then we need to set the padding and margins:
list-style-type: none;
margin: 0px;
padding: 5px 0px 5px 0px;
The gradient is drawn on the <ul> instead of the individual <li>s. This gradient starts at 60% opacity and fades to 30% half-way, then has a harsh break to 20% until it fades out entirely. So, let’s add the gradient now:
background-image: -webkit-gradient(linear,
left top, left bottom,
color-stop(0.0, rgba(255, 255, 255, 0.6)),
color-stop(0.5, rgba(255, 255, 255, 0.3)),
color-stop(0.5, rgba(255, 255, 255, 0.2)),
color-stop(1.0, rgba(255, 255, 255, 0.0)));
background-image: -moz-linear-gradient(top,
rgba(255, 255, 255, 0.6) 0%,
rgba(255, 255, 255, 0.3) 50%,
rgba(255, 255, 255, 0.2) 50%,
rgba(255, 255, 255, 0.0) 100%);
Now add a one pixel highlight at the top, if you like. As with the CSS buttons, we need to specify one line for Webkit, one for Mozilla, and one for Opera.
-webkit-box-shadow: inset 0px 1px 0px rgba(255, 255, 255, 0.5);
-moz-box-shadow: inset 0px 1px 0px rgba(255, 255, 255, 0.5);
box-shadow: inset 0px 1px 0px rgba(255, 255, 255, 0.5);
The last thing we need to do for the <ul> is to set the background color, text color, and text alignment:
background-color: #222;
color: #fff;
text-align: center;
So, now that we have the list set up, we need to style its individual items. We need to make each item an inline-block element. Then we set margins and padding as well as a minimum width. To make the interface more application-like, we should also set the cursor to the default. You may also want it to look like a pointer, as if the buttons were links.
display: inline-block;
margin: 0px;
padding: 3px 5px 3px 5px;
min-width: 100px;
cursor: default;
It is very important to note that all of the major browsers render whitespace between inline elements (including inline-block) as a single space. So if your toolbar has spacing between the items, it’s probably because you have the next item on a new line. There are a couple of ways around this. Firstly, you could use a negative margin on all but the first element; this works pretty well, but it’s hard to give a space a pixel-width, as font size and other variables may change it. Secondly, you could just put everything on one line; for small toolbars, this is probably your best bet. Lastly, you could comment out all the whitespace:
<ul class=”toolbar” style=”background-color: #700”>
<li>This</li><!––
––><li>toolbar</li><!––
––><li>is</li><!––
––><li>red!</li>
</ul>
Since we have multiple items side-by-side, we don’t want two borders being drawn next to each other. Here we set only the top, bottom, and left borders. We’ll add the right border for the last item later.
border: 1px solid rgba(0, 0, 0, 0.5);
border-width: 1px 0px 1px 1px;
By using an inset box shadow, we can add a subtle highlight border inside each of our items. At the same time, we should draw a highlight underneath the item, to make it look as if it is set within the toolbar.
-webkit-box-shadow: 0px 1px 1px rgba(255, 255, 255, 0.2),
inset 0px 0px 2px rgba(255, 255, 255, 0.25);
-moz-box-shadow: 0px 1px 1px rgba(255, 255, 255, 0.2),
inset 0px 0px 2px rgba(255, 255, 255, 0.25);
box-shadow: 0 1px 1px rgba(255, 255, 255, 0.2),
inset 0px 0px 2px rgba(255, 255, 255, 0.25);
To make the items animate on hover in Webkit, we can set up a transition for the background property:
-webkit-transition: background 0.2s ease-in-out;
Now we need to set the font size to be small and bold, and draw a drop shadow above the text.
text-shadow: rgba(0, 0, 0, 0.5) 0px -1px 0px;
font-size: 8pt;
font-weight: bold;
The toolbar now looks mostly fine—we just need to add rounded borders to the first and last item and then give the last item a right border. For this, we can use the CSS pseudo-classes :first-child and :last-child.
ul.toolbar li:first-child {
border-radius: 3px 0px 0px 3px;
-moz-border-radius: 3px 0px 0px 3px;
}
ul.toolbar li:last-child {
border-radius: 0px 3px 3px 0px;
-moz-border-radius: 0px 3px 3px 0px;
border-width: 1px;
}
To set up hover and click states, we can use :hover and :active to set the background. For the clicked state, we should set the Webkit transition time to instantaneous. Here, the hover state is also used by the selected class, which you could use for the currently selected item.
ul.toolbar li.selected, ul.toolbar li:hover {
background-color: rgba(255, 255, 255, 0.25);
}
ul.toolbar li:active {
background-color: rgba(0, 0, 0, 0.3);
-webkit-transition-duration: 0.0s;
}
The last thing we need to do to make the toolbar complete is add a class for items which have icons. The best way to add icons is to set them as the background image of the item, which will ensure they are the same size as the text-only items.
ul.toolbar li.icon {
min-width: 0px;
padding-left: 30px;
background-repeat: no-repeat;
background-position: 10px center;
}
To see examples of the toolbars in action, head over to the Sexy CSS Toolbars page in my Experiments.
CSS is getting quite powerful these days. It can even take the place of images in many ways, giving you a more flexible design and fewer files to work with. Imagine being able to make an ultra sexy button with just CSS, giving you complete control through code. Well, you can! And it’s not too difficult, really. Below you can see some buttons I styled using only CSS:

Sexy, yes? These employ a couple of useful CSS properties. Most importantly are gradients, for which we use -webkit-gradient and -moz-linear-gradient. Secondly, we use border-radius and -moz-border-radius to make the button round. For a bit of added depth and eye candy, I have added a subtle drop black dropshadow above the text using text-shadow and around the whole button using -webkit-box-shadow, -moz-box-shadow, and box-shadow.
You may have noticed a lot of “webkit” or “moz” above. Everything used to create these buttons works in both Webkit browsers as well as Mozilla browsers—they just work a little differently. Internet Explorer does not have any of the functionality required to make a button like this, and Opera lacks quite a few things as well. It degrades fairly well in Opera (as it still has border-radius), and Internet Explorer users get a solid gray rectangle with a black border. So what does this mean for us as developers? Well, it’s not something we can rely on in the wild—but it works perfectly for those targetting Mozilla or Webkit users.
Alright, now let’s start looking at some code. Of course, we’ll create our button as usual: <input type=”button” value=”Cancel” />. To style all inputs with the type of “button” as well as the button element, we can use the CSS selector input[type=button], button.
We’ll start by changing our button’s outline and radius. We need to set the outline-width to 0 to avoid Webkit drawing an ugly border around it when focused. Because there is no outline-radius property, Webkit draws a rectangular border on focused elements. We set border-radius and -moz-border-radius to 50px, which will make our buttons as round as possible up to a height of 50 pixels.
outline-width: 0;
border: 1px solid #000;
border-radius: 50px;
-moz-border-radius: 50px;
Now let’s set up the drop shadow for the whole button. We need one line for Webkit, one for Mozilla, and the real CSS3 property, which is used by Opera:
-webkit-box-shadow: 0px 1px 3px rgba(0, 0, 0, 0.5);
-moz-box-shadow: 0px 1px 3px rgba(0, 0, 0, 0.5);
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.5);
And now to make the buttons really sexy: add the gradient. These differ a little between browsers. We need to specify to -webkit-gradient that we are using a linear gradient. For Mozilla, we specify that we want a linear gradient by using -moz-linear-gradient. Then we specify the angle (for instance, from the top left to the bottom left). Webkit’s color-stops are backwards from Mozilla’s colors (which require no extra function). Mozilla can also use pixel values or percentages, whereas Webkit can only use percentages.
background-image: -webkit-gradient(linear,
left top, left bottom,
color-stop(0.0, rgba(255, 255, 255, 0.8)),
color-stop(0.01, rgba(255, 255, 255, 0.6)),
color-stop(0.4, rgba(255, 255, 255, 0.3)),
color-stop(0.4, rgba(255, 255, 255, 0.2)),
color-stop(1.0, rgba(255, 255, 255, 0.0)));
background-image: -moz-linear-gradient(top,
rgba(255, 255, 255, 1.0) 0%,
rgba(255, 255, 255, 0.6) 1px,
rgba(255, 255, 255, 0.3) 40%,
rgba(255, 255, 255, 0.2) 40%,
rgba(255, 255, 255, 0.0) 100%);
It is important to note that CSS gradients act as an image—in this case, the background image. The leverage to this design comes from the fact that we use RGBA colors; that is, no part of the gradient is fully opaque, and thus the color underneath can shine through. This is very important when using Webkit transitions, as you cannot transition from one gradient to another—but you can transition from one background color to another.
It is possible to specify an inner drop shadow which will act as the shiny highlight, rather than specify it in the gradient. This works in Mozilla and Opera; the odd man out in this case is Webkit, as there is a bug preventing it from rendering correctly. You can add another line to -moz-box-shadow and box-shadow to get the effect:
-moz-box-shadow: 0px 1px 3px rgba(0, 0, 0, 0.9),
inset 0px 1px 0px rgba(255, 255, 255, 0.5);
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.9),
inset 0px 1px 0px rgba(255, 255, 255, 0.5);
Now we just need to set up the initial background color, text color, and the text drop shadow:
background-color: #444;
color: #fff;
text-shadow: rgba(0, 0, 0, 0.5) 0px -1px 0px;
So, now we have a styled sexy button. But it doesn’t quite act like a button yet. We need to add some styling for when the button is hovered, focused and clicked.
To add a bit more eye candy, we can use Webkit transitions to ease between the states. Add this -webkit-transition to the button’s normal CSS mode to ease between the background color, text color, and drop shadow:
-webkit-transition: background 0.2s ease-in-out,
color 0.2s ease-in-out,
-webkit-box-shadow 0.2s ease-in-out;
To style the hover and focus states, we will use the selector input[type=button]:hover, input[type=button]:focus, button:hover, button:focus. This ensures that we can style the button for those who use the mouse as well as for keyboard navigators. Fortunately, most of the inherited styles will still apply to the hover state. All we need to do is change a few key properties. Here I darken the drop shadow and lighten the background color:
-webkit-box-shadow: 0px 1px 3px rgba(0, 0, 0, 0.9);
-moz-box-shadow: 0px 1px 3px rgba(0, 0, 0, 0.9);
background-color: #666;
For the click state, we use the input[type=button]:active, button:active selector. Like with the hover state, we just need to change a few things. Here I darken the background and text and change the transition to be instantaneous:
background-color: #222;
color: #ccc;
-webkit-transition-duration: 0.0s;
So, now we have a completely functional sexy button, all created with CSS! Play around with the settings to create a button which fits your style. Check out the Sexy Buttons page in my Experiments to see them in action!
Update: I have added Mozilla and Opera transitions to the buttons. You can read more about the code changes in the update post.