Friday, June 17, 2011

Styling the Button Element with CSS Sliding Doors - now with Image Sprites and IE 8 Support

Examples

The buttons shown use the same markup and style — only the label text is different.
View in a new window

Sprite image

The background sprite contains four images: each button has a left and right "door," and each door has two states, default and hover. Update 4/27/09: Our example button now references a single sprite image for both doors and their hover states as shown (thanks to Louis Walch for the update!):
Button sprite
We recommend adding at least 20px vertical space between the stacked states to prevent one state from appearing when it should be hidden. (We could add "overflow: hidden" to the button rule instead, but doing so would mean that we'd have to reinstate conditional styles for IE, which requires that the overflow property be visible — otherwise you may see extra right and left padding in IE. We figure this is a reasonable workaround to avoid having to maintain separate style blocks.)

Markup

Button markup consists of a button tag around a span tag, and label text is written into the span. Both tags are necessary to support the sliding door background images: the button tag's background image is shorter with right corners, and the span's background image is larger with left corners. We found in our tests that the right image should be at least as wide as it is tall to avoid gaps between the doors.
And last but not least, we assigned a class to the button element to apply our design; in this case, "submitBtn." Styles for the span tag are assigned with descendant selectors.

CSS

/* REQUIRED BUTTON STYLES: */  
button { 
 position: relative;
 border: 0; 
 padding: 0;
 cursor: pointer;
 overflow: visible; /* removes extra side padding in IE */
}

button::-moz-focus-inner {
 border: none;  /* overrides extra padding in Firefox */
}

button span { 
 position: relative;
 display: block; 
 white-space: nowrap; 
}

@media screen and (-webkit-min-device-pixel-ratio:0) {
 /* Safari and Google Chrome only - fix margins */
 button span {
  margin-top: -1px;
 }
}


/* OPTIONAL BUTTON STYLES for applying custom look and feel: */  
button.submitBtn { 
 padding: 0 15px 0 0; 
 margin-right:5px; 
 font-size:2em; 
 text-align: center; 
 background: transparent url(images/btn_blue_sprite.gif) no-repeat right -140px; 
}
 
button.submitBtn span {
 padding: 13px 0 0 15px; 
 height:37px; 
 background: transparent url(images/btn_blue_sprite.gif) no-repeat left top; 
 color:#fff; 
}
 
button.submitBtn:hover, button.submitBtnHover { /* the redundant class is used to apply the hover state with a script */
 background-position: right -210px; 
}
 
button.submitBtn:hover span, button.submitBtnHover span {
 background-position: 0 -70px;
}

Supported Browsers

So far it works in:
  • IE 6+
  • Firefox 1.5+
  • Opera 8+
  • Safari 3+
  • Chrome 1.0
Update 4/27/09: The button styles now work in Chrome — thanks again, Louis!

Caveats

IE 6 does not support the ":hover" pseudoclass on elements other than anchor tags. To get the hover to work in IE6, create a class that duplicates the :hover styles, and then script a function to toggle that class on/off like the one below written with jQuery: