Styling buttons with CSS3

CSS3 introduces new possibilities for styling buttons. Effects that previously required the use of images can now be accomplished purely with CSS. The buttons below demonstrate three possibilities: a button with a subtle gradient and rounded corners, a button with a glassy effect, and a button with an image and slight rollover effect.

The starting point

The starting point for all of the examples on this page is the following HTML — a button element containing two span elements:

1
<button><span><span>Button text</span></span></button>

We remove the default button styling with the following style rules:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
button{
  margin      : 0;
  padding     : 0;
  border      : 0;
  background  : transparent;
  font-family : inherit;
  font-size   : 1em;
  cursor      : pointer;
}

button::-moz-focus-inner{
  padding : 0;
  border  : 0;
}

Lines 6 and 7 ensure the button inherits the typeface and text size of the surrounding content; these can be modified if the text style used for normal text is not suitable for user interface controls. Line 8 instructs the browser to use the ‘pointer’ style for the mouse pointer; this style is used to indicate that an element can be clicked. Lines 11 to 14 are required by Firefox in order to remove all of the space around the button’s content.

Next we instruct the browser to treat the span elements as block-level elements in order to make them easier to style (while using div elements would have had the same effect, a div element inside a button is invalid HTML):

1
2
3
button span{
  display : block;
}

Button borders

The border property is used to give the button a border. The CSS3 border-radius property allows the button to be given rounded corners. For example:

1
2
3
4
button > span{
  border        : 1px solid rgb(128,128,128);
  border-radius : 4px;
}

Line 2 gives the button a grey border one pixel wide. Line 3 gives the button rounded corners with a radius of four pixels. In older browsers without support for the border-radius property the corners will remain square.

The button may be given a double stroke by putting another border on the inner span element, with a reduced border radius:

1
2
3
4
button > span > span{
  border        : 1px solid rgb(192,192,192);
  border-radius : 3px;
}

Line 2 gives the button a inner light grey border one pixel wide. Line 3 ensures the inner border fits neatly within the outer border: the radius of the inner border equals the radius of the outer border minus the outer border width.

Note that the selectors on rest of this page assume a single border; in the case of a double border the selectors must be modified to refer to the inner span element.

Button backgrounds

The background property is used to style the button background. CSS3 introduces the linear-gradient function to create background gradients without using images:

1
2
3
4
5
6
7
8
button > span{
  background       : rgb(192,192,192);
  background-image :    -moz-linear-gradient(rgb(224,224,224),rgb(160,160,160));
  background-image :     -ms-linear-gradient(rgb(224,224,224),rgb(160,160,160));
  background-image :      -o-linear-gradient(rgb(224,224,224),rgb(160,160,160));
  background-image : -webkit-linear-gradient(rgb(224,224,224),rgb(160,160,160));
  background-image :         linear-gradient(rgb(224,224,224),rgb(160,160,160));
}

The six different style rules are used to support various browsers. Line 7 is the pure CSS3 rule: it sets the background image to a linear gradient with the first colour (a light grey) at the top of the button and the second colour (a slightly darker grey) at the bottom of the button. Before this part of the CSS3 specification was finalised, various web browsers added support using vendor prefixes — a way for browser makers to experiment with new features without causing compatibility problems. Lines 3 to 6 ensure the intended effect of line 7 is implemented in Firefox, Internet Explorer, Opera, and Chrome and Safari respectively. Finally, line 2 provides a flat background colour for older browsers that lack support for the linear-gradient function.

It is possible to use the linear-gradient function with more than two colours. In this case, the intermediate colours (known as stops) can be followed by a percentage value giving their location in the gradient. For example, the following style rule (with the addition of the vendor prefix variations) creates a more glassy gradient:

1
background-image : linear-gradient(
  rgb(224,224,224),rgb(192,192,192) 50%,rgb(160,160,160) 50%,rgb(192,192,192));

This rule fades from a light grey to slightly darker grey over the top half of the button, and then from a darker grey back to the second grey over the bottom half of the button.

Button text

To create space around the button text we use the padding property to pad the text horizontally, and the line-height property to pad the text vertically:

1
2
3
4
button > span{
  padding     : 0 8px;
  line-height : 24px;
}

The color property is used to set the text colour. The CSS3 text-shadow property can be used to enhance the contrast of the text relative to the background:

1
2
3
4
button > span{
  color       : white;
  text-shadow : 0 0 2px black;
}

Line 3 gives the text a black shadow to improve the text contrast. The first two numbers in the value set the shadow offset — in this case the shadow is directly behind the text. The third number sets the spread of the shadow — in this case two pixels, in order to keep the effect subtle. The final part of the value sets the shadow colour. For dark text, the ‘shadow’ should be a light colour. Older browsers do not support the text-shadow property, so you should ensure that there is enough contrast to read the text without it.

Button images

Buttons can use images by replacing the button text with an image element in the HTML. However, there are advantages to replacing the text with an image in the stylesheet instead — specifically, the image can change when the visitor hovers over the button. To replace the text with an image, use CSS of the following form:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
button > span{
  width       : 24px;
  height      : 24px;
  background  : rgb(192,192,192) url('image.png') no-repeat center center;
  line-height : 24px;
}

button > span > span{
  visibility : hidden;
}

Lines 2 and 3 set the size of the button. Line 4 displays the button image. Note that while the image can be displayed above a flat colour, as shown above, it cannot be displayed above a gradient; this is because the result of the linear-gradient function is itself an image. Line 5 sets the line height, which ensures that buttons with images line up with neighbouring text buttons. Line 9 hides the text; the text should still be left in the HTML as it improves the accessibility of the page.

Where now?

Found this useful? Share it:

Also in HTML and CSS: