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

Posted by Maggie on 04/24/2009

We dusted off our original sliding doors button to give it a much needed update. The button now works with image sprites thanks to the CSS contributions of Louis Walch, and also works with a single block of CSS (we’ve removed the now unnecessary conditional comments for IE) in all major browsers including IE versions 6 through 8.

For those not familiar, form buttons are notoriously difficult to customize because they render differently across browsers and platforms. A few methods for styling buttons are commonly used to make them appear dimensional, uniform, and consistent across browsers, however each has limitations:

  • Apply a single, unique background image with the text “baked in” for each type of button (i.e., “Submit”, “Send message”) and its rollover state. This approach is consistent across browsers but doesn’t scale; you have to create an image for every button in your site, which may not be reasonable to maintain or update. Also, image text is not accessible so a redundant text equivalent must be included in all button markup.
  • Tile a background image on the button element. This works really well when you only need rectangular buttons or have the option to use the CSS3 “border-radius” property to apply rounded corners, as demonstrated in our article on styling buttons with the jQuery UI CSS framework. However, it falls short if your design calls for a custom shape, like a polygon, or if rounded corners must be applied consistently across all browsers, in which case you’d need to create a workaround in JavaScript for browsers that don’t yet support the border-radius property, like IE.
  • Use only background colors, borders and icons as demonstrated by Kevin Hale at Particle Tree. This method requires only basic CSS and minimal extra markup, however the style options are very limited and may not reflect the richness of your design.

While these methods may work in particular situations, we needed a more flexible solution that accommodated a wider range of styles.

Our solution

We’re often designing and developing complex applications with buttons that are styled with background images, background colors, icons, and sometimes a combination of all three. Ideally, our buttons would:

  • use the sliding doors method introduced on A List Apart so that we can employ dimensional background images in various shapes and allow the background to scale with the text size to some degree,
  • use sprite images, where multiple button states are combined into a single image file and repositioned on hover, to limit the number of image downloads,
  • allow us to use HTML text for the button labels so that we could reuse the same button style many times without having to cut unique images for each, and
  • not require JavaScript for form submission or rollovers to ensure that the buttons are usable without JavaScript enabled.

The result is a cross-browser method for styling button elements with sliding door sprites.

Examples

The buttons shown use the same markup and style — only the label text is different.

Demo Page

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!):

Buttonsprite

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.

<button value="submit" class="submitBtn"><span>Submit</span></button>

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:

<script type="text/javascript">
$(function(){
    $('.submitBtn').hover(
        // mouseover
        function(){ $(this).addClass('submitBtnHover'); },

        // mouseout
        function(){ $(this).removeClass('submitBtnHover'); }
    );
});
</script>

Credits

Our original button styling technique was motivated by the Particle Tree article, Rediscovering The Button Element by Kevin Hale. Louis Walch provided updated CSS to support sprites and also helped us debug the final examples shown here.

600

Comments

<div id="commentNumber1" class="commentEntry">
<p>Excellent work, guys. We’re currently in the middle of a redesign at work and I’m dying to get away from the ‘baked in’ image buttons. I think I’ll present this article at our next designers meeting. :)

</div>
    <p class="posted"><a href="#commentNumber1">Comment</a> by

Mike T. on 04/27  at  11:04 AM

<div id="commentNumber2" class="commentEntry">
<p>the “right corner” images are off by 1 pixel up in Chrome 2.0.174.0

other than that, very nice work

</div>
    <p class="posted"><a href="#commentNumber2">Comment</a> by

Luka Kladaric on 04/27  at  11:13 AM

<div id="commentNumber3" class="commentEntry fg">
<p>@ Luka Kladaric:&nbsp; we tried to come up with a workaround for Chrome, but no luck.&nbsp; It seems to be an issue with the way Chrome renders the button element because removing padding/margin/borders/you-name-it had no effect.&nbsp; If you—or anyone else out there—know of a fix that won’t break the styling in Safari, please share!

</div>
    <p class="posted"><a href="#commentNumber3">Comment</a> by

Maggie (Filament) on 04/27  at  11:20 AM

<div id="commentNumber4" class="commentEntry fg">
<p>@Mike T:&nbsp; thanks!&nbsp; Glad we could be of help. :)

</div>
    <p class="posted"><a href="#commentNumber4">Comment</a> by

Maggie (Filament) on 04/27  at  11:21 AM

<div id="commentNumber5" class="commentEntry">
<p>Nice to see this done with a button element. Why did you decide to not incorporate both the long and short images into one sprite?

</div>
    <p class="posted"><a href="#commentNumber5">Comment</a> by

Ryan on 04/27  at  11:28 AM

<div id="commentNumber6" class="commentEntry">
<p>@Ryan, it’s actually my fault that it was not built into one sprite. Not sure why I couldn’t get it to work when I originally did this, but here are the changes needed to make this into a single sprite:

@Luka & Maggie : I actually may have discovered a workaround for the Chrome problem as well. Css updated below. Tested in IE6, IE7, Safari 3, FF and Chrome.

New Sprite:
http://louiswalch.com/beta/btn_blue_sprite.gif

CSS:
http://pastie.org/460158

@Maggie: Feel free to delete this comment after you roll this in. Sorry for not realizing this before you went to press.

</div>
    <p class="posted"><a href="#commentNumber6">Comment</a> by

Louis W on 04/27  at  03:09 PM

<div id="commentNumber7" class="commentEntry fg">
<p>@Louis W:&nbsp; Nice work!&nbsp; We’ve incorporated it into the examples in this post.&nbsp; Thanks again!&nbsp; :)

</div>
    <p class="posted"><a href="#commentNumber7">Comment</a> by

Maggie (Filament) on 04/27  at  04:19 PM

<div id="commentNumber8" class="commentEntry">
<p>confirm working in Chrome 2.0.174.0 :) good job, guys!

</div>
    <p class="posted"><a href="#commentNumber8">Comment</a> by

Luka Kladaric on 04/27  at  05:35 PM

<div id="commentNumber9" class="commentEntry">
<p>For the future it would be easier to create a &lt;div&gt; &lt;/div&gt; tag in order to present a sample of the CSS embedded directly on the website herein. This is needed for example in my case because it’s kinda tricky to load each CSS and test it on my rent a car site. Otherwise, just wanted to say that your scripts are great!

</div>
    <p class="posted"><a href="#commentNumber9">Comment</a> by

Masini Inchirieri Bucuresti on 05/01  at  11:56 AM

<div id="commentNumber10" class="commentEntry">
<p>Could someone explain:

@media screen and (-webkit-min-device-pixel-ratio:0) {
/* Safari and Google Chrome only - fix margins */
button span {
margin-top: -1px;
}
}
Dreamweaver is highlighting this as code error not seen this befor
Thanks Mike

</div>
    <p class="posted"><a href="#commentNumber10">Comment</a> by

Mike Gadd on 05/06  at  02:31 AM

<div id="commentNumber11" class="commentEntry">
<p>@mike:

The CSS you included is a css hack which will make the enclosed styles only apply to Chrome and Safari. It is needed in order to fix a problem with how margins are applied to the button in Google Chrome.

It is ok if Dreamweaver is highlighting this as invalid - in a way it is. But leave it in there if you would like your buttons to appear correctly across all browsers

If your interested in more browser specific css hacks check out this page:
http://ajaxian.com/archives/css-browser-hacks

</div>
    <p class="posted"><a href="#commentNumber11">Comment</a> by

Louis W on 05/06  at  08:25 AM

<div id="commentNumber12" class="commentEntry">
<p>Feel free to add Safari 2 (2.0.4 aka 419.3) on your supported browsers list.

</div>
    <p class="posted"><a href="#commentNumber12">Comment</a> by

Michał on 05/12  at  10:32 AM

<div id="commentNumber13" class="commentEntry">
<p>In IE8 when the button is click, there’s a pixel missing from the bottom (and top) on the right side of the button.&nbsp; Is there a way to fix this?

</div>
    <p class="posted"><a href="#commentNumber13">Comment</a> by

Jane on 05/20  at  08:56 PM

<div id="commentNumber14" class="commentEntry">
<p>I think the efficiency of the CSS paired with clean visual design here are great. I’m a fan of Filament, as well as Bowman’s ‘Sliding Doors’ and Cederholm’s ‘Bullet-Proof’ philosophies/techniques.

What I’m most interested in is IF you do employ this CSS/<button> tag technique in your site design and architecture:

How is everyone getting around the issues that IE incorrectly submits the inner HTML of the <button> or returns all values to all buttons when multiple buttons exist on a page?

I’m a visual web designer for a team of developers that would come along with me on this technique--except for the IE issue, which may simplify the HTML/CSS but complicates the form submission to a painful level.

Thanks,
Chris

Examples:
http://www.experts-exchange.com/Software/Internet_Email/Web_Browsers/Q_21599546.html

http://www.w3schools.com/tags/tag_button.asp

http://msdn.microsoft.com/en-us/library/ms535211(VS.85).aspx
“New for Internet Explorer 8 Internet Explorer 8 and later. When the BUTTON element is submitted in a form, the value depends on the current document compatibility mode. In IE8 mode, the value attribute is submitted. In other document modes and earlier versions of Internet Explorer, the innerText value is submitted.”

</div>
    <p class="posted"><a href="#commentNumber14">Comment</a> by

Sabatino on 05/25  at  11:47 PM

<div id="commentNumber15" class="commentEntry">
<p>Doesn’t seem to be working for me in IE7 compatibility mode (IE8) on <a href="http://bookhookup.net/sell" rel="nofollow">http://bookhookup.net/sell</a>. To replicate, enter any bogus value and try clicking “Get Started"… it won’t submit.

CSS is unchanged from the example (except for custom padding values)
Markup is as follows (minus spaces of course ;) ): < button value="submit" class="formbutton">< span>Get Started</ span></ button >

</div>
    <p class="posted"><a href="#commentNumber15">Comment</a> by

Joe on 06/06  at  06:20 PM

<div id="commentNumber16" class="commentEntry">
<p>@Joe

Your are missing a type on your button. If you want it to submit you need type="submit"

Types can be any of:
button <- default
submit <- will submit the current form the button is in
reset <- will reset the current form the button is in

</div>
    <p class="posted"><a href="#commentNumber16">Comment</a> by

dotnetCarpenter on 06/11  at  03:01 PM

<div id="commentNumber17" class="commentEntry">
<p>@dotnetCarpenter D’oh! Thanks so much, dunno why I missed that.

</div>
    <p class="posted"><a href="#commentNumber17">Comment</a> by

Joe on 06/11  at  07:50 PM

<div id="commentNumber18" class="commentEntry">
<p>Could you post an example of this problem? I use multiple buttons using this method throughout my web apps without issue.

</div>
    <p class="posted"><a href="#commentNumber18">Comment</a> by

LouisW on 06/13  at  10:25 AM

<div id="commentNumber19" class="commentEntry">
<p>@LouisW: Hi, since you’re using multiple buttons thoughout your web app, I’d ask you too if you have any advice or insight that you use to support IE, even back to IE6 on this issue: [see earlier post]

“How is everyone getting around the issues that IE incorrectly submits the inner HTML of the <button> or returns all values to all buttons when multiple buttons exist on a page? “
http://msdn.microsoft.com/en-us/library/ms535211(VS.85).aspx
[copy/paste this to view--parens don’t survive in the comments]

Thanks,
Chris

</div>
    <p class="posted"><a href="#commentNumber19">Comment</a> by

sabatino on 06/13  at  10:57 AM

<div id="commentNumber20" class="commentEntry">
<p>@Jane The best option I’ve found to fix the 1px background shift in IE8 is using Microsoft’s CSS vendor extensions (which work in IE8 but not previous versions). I’ve documented the solution here: <a href="http://bit.ly/NSd0b" rel="nofollow">http://bit.ly/NSd0b</a>.

</div>
    <p class="posted"><a href="#commentNumber20">Comment</a> by

Cory Duncan on 06/20  at  02:41 PM

<div id="commentNumber21" class="commentEntry">
<p>Hello guys, great example, but I have some trouble with Opera 9.24. The &lt;button&gt; background goes down on about 2px. If you have any sollution, please sent the link on it. Thx.

</div>
    <p class="posted"><a href="#commentNumber21">Comment</a> by

Roman on 07/02  at  05:21 PM

<div id="commentNumber22" class="commentEntry">
<p>Thanks for this great article.

While playing with the demo i’ve noticed 2 things:
In Firefox 3.5 there’s an extra gap inside the button, to remove id add padding:0 (it’s Mozilla’s forms.css issue) :

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

Second issue: under the button there’s about 5 pixel space in IE. (It’s easy to notice, when you have image without transparent gaps between the sprites). To get rid of it just add overall height to button.submitBtn:

button.submitBtn {
height:50px; (37px height + 13px top padding)
padding: 0 15px 0 0;
...
}

</div>
    <p class="posted"><a href="#commentNumber22">Comment</a> by

nmstudio on 07/06  at  04:25 PM

<div id="commentNumber23" class="commentEntry">
<p>Man nmstudio, good find on the focus inner problem. That was driving me nuts and wouldn’t show up ANYWHERE in firebug.

</div>
    <p class="posted"><a href="#commentNumber23">Comment</a> by

Bob Spryn on 07/18  at  04:24 PM

<div id="commentNumber24" class="commentEntry">
<p>So here’s an odd problem.

With firefox 3.5 and Firebug 1.4 things look fine… until you open the firebug panel.

It looks like for some reason as soon as you open firebug, firefox now understands this rule:

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

Try it out! Weird eh?

</div>
    <p class="posted"><a href="#commentNumber24">Comment</a> by

Bob Spryn on 07/18  at  04:55 PM

<div id="commentNumber25" class="commentEntry">
<p>Here’s my new button. It donesn’t need extra markup like spans or b tags and yet it’s transparent without opaque corners or background to hide the other half. It submits hitting enter, because it IS the actual submit button, not a link with JS submit function.

I named it “the levitating submit button”, since in hangs completely out of the label tag.
http://seosumo.com/simplest-transparent-css-submit-button-ever

</div>
    <p class="posted"><a href="#commentNumber25">Comment</a> by

sergio zambrano on 07/23  at  04:56 PM

<div id="commentNumber26" class="commentEntry">
<p>Great stuff… I did notice in chrome a one pixel shift when you’re not viewing 100%, but zoomed in or out.

</div>
    <p class="posted"><a href="#commentNumber26">Comment</a> by

Michael Torfs on 08/01  at  04:21 PM

<div id="commentNumber27" class="commentEntry">
<p>Hi all

first of all nice job and keep it up on the fantastic improvements!

i only have one minor prob, im getting an irritating 2px margin on the left hand side of the button only in IE but ff and safari are perfect, any idea why this is happening?

http://skitch.com/marioborg/b4mqn/ieprob

Regards
Mario

</div>
    <p class="posted"><a href="#commentNumber27">Comment</a> by

Mario Borg on 08/06  at  04:05 AM

<div id="commentNumber28" class="commentEntry">
<p>Hi there,

just a quick update. this is my css based on yours which i found just seems to tidy things up (odd padding differences etc). Iv tested on chrome ie8 and firefox but cannot test in safari or earlier ie’s as don’t have access. don’t know if its valid etc but it seems to make the buttons look very very similar across the 3 browsers iv tested:

button.submit-btn {
position: relative;
border: 0;
padding: 0 3px 0 0;
margin: 0;
cursor: pointer;
overflow: visible; /* removes extra side padding in IE */
font: 12px Arial, Helvetica, sans-serif;
font-weight: bold;
text-align: center;
background: transparent url(’../images/button.gif’) no-repeat right -62px;
}

button.submit-btn span {
position: relative;
display: block;
white-space: nowrap;
line-height: 21px;
padding: 0 8px 0 10px;
height: 21px;
background: transparent url(’../images/button.gif’) no-repeat left top;
color: #2F6681;
}

button.submit-btn:hover, button.submit-btn-hover { /* the redundant class is used to apply the hover state with a script */
background-position: right -93px;
}

button.submit-btn:hover span, button.submit-btn-hover span {
background-position: 0 -31px;
}

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

button.submit-btn::-moz-focus-inner {
margin-right: -3px; /* overrides extra padding in Firefox */
}

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

my button state images are 21px high with 10px in between each state

thanks for the good work

ben

</div>
    <p class="posted"><a href="#commentNumber28">Comment</a> by

Ben Grice on 08/13  at  10:09 AM

<div id="commentNumber29" class="commentEntry">
<p>Could you post an example of this problem? I use multiple buttons using this method throughout my web apps without issue

</div>
    <p class="posted"><a href="#commentNumber29">Comment</a> by

توبيكات on 08/15  at  07:15 PM

<div id="commentNumber30" class="commentEntry">
<p>this post made my day(weel, night actually, its 11PM here). thnx a lot :)

</div>
    <p class="posted"><a href="#commentNumber30">Comment</a> by

Razvan Pavel on 08/18  at  02:57 PM

<div id="commentNumber31" class="commentEntry">
<p>توبيكات , no problem, like i said my changes just seemed to tidy up some little pixel differences here and there. may just be me tho so i wouldn’t take it as right. Just thought id add the comment on the off chance that someone was having slight differences so they could try what worked for me.

Cheers
Ben

</div>
    <p class="posted"><a href="#commentNumber31">Comment</a> by

Ben Grice on 08/19  at  04:17 AM

<div id="commentNumber32" class="commentEntry">
<p>I am curious to find out if anyone has found a way to incorporate a pressed button state into this CSS?

I would like to add the ability to have the button simulate a pressed state upon the click when submitting the form.

Also, has anyone come up with a proper fix for the bug in IE8 involving the 1 pixel shift when you click on the button. I read the following article

http://bit.ly/NSd0b

but I wasn’t sure if there had been further solutions identified.

Any help would be greatly appreciated. This is an excellent method for adding nice touches to boring form buttons!!!! Thanks to folks like you who make designing new and fulfilling everyday!

</div>
    <p class="posted"><a href="#commentNumber32">Comment</a> by

Tim Wilson on 08/25  at  04:33 PM

<div id="commentNumber33" class="commentEntry">
<p>For a pressed button state just add a :active class (identical to how :hover is.

Your bit.ly url is 404ing.

</div>
    <p class="posted"><a href="#commentNumber33">Comment</a> by

Louis W on 08/25  at  04:46 PM

<div id="commentNumber34" class="commentEntry">
<p>Thanks for the info on the active class, I will run with that....

I checked the other URL and it seems to work fine for me:

http://bit.ly/NSd0b

I am seeing a 1 pixel shift on the right side of the button in IE8 and all looks well in Chrome.

The URL referenced above mentions a few suggested fixes, but all of them have their downsides. i am curious to know if everyone that uses this is seeing the same issue in IE8?

Any insight would be greatly appreciated!

</div>
    <p class="posted"><a href="#commentNumber34">Comment</a> by

Tim Wilson on 08/25  at  11:06 PM

<div id="commentNumber35" class="commentEntry">
<p>Tim, did you ready my comment “Ben Grice on 08/13  at  10:09 AM”? i made a few changes that seemed to work for me, that why i posted them. try what i changed and see if that helps?

Cheers Ben

</div>
    <p class="posted"><a href="#commentNumber35">Comment</a> by

Ben Grice on 08/26  at  05:05 AM

<div id="commentNumber36" class="commentEntry">
<p>Ben,

Thanks for the response, however I performed a diff on your posted code and my code and tried using your version and I actually ended up with the same 1px shift in IE8 and ended up causing another alignment issue with Chrome.

Therefore, I reverted back to the code I was using previously as it seems to work in all required browsers. Now the only issue I need to solve is still the IE8 1px shift issue.

Can someone take a look at my code below to see if there may be a solution for this issue as I would love to use this as a solution for an ongoing project, but cannot until I have some plausible fix for the IE8 pixel issue:

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.submit-btn {
position: relative;
border: 0;
padding: 0 15px 0 0;
margin-right: 5px;
font-size:2em;
text-align: center;
overflow: visible; /* removes extra side padding in IE */
font-weight: bold;
text-align: center;
background: transparent url(btn_blue_sprite.gif) no-repeat right -140px;
}
button.submit-btn span {
position: relative;
display: block;
white-space: nowrap;
padding: 7px 0 0 15px;
height: 44px;
background: transparent url(btn_blue_sprite.gif) no-repeat left top;
color: #FFFFFF;
}
button.submit-btn:hover, button.submit-btn-hover { /* the redundant class is used to apply the hover state with a script */
background-position: right -210px;
}

button.submit-btn:hover span, button.submit-btn-hover span {
background-position: 0 -70px;
}

</div>
    <p class="posted"><a href="#commentNumber36">Comment</a> by

Tim Wilson on 08/26  at  12:26 PM

<div id="commentNumber37" class="commentEntry">
<p>I ran into a problem that seemed to affect only Google Chrome (and not Safari 4).

There was a gap appearing between the button bg image and the span bg image. Turns out the right part of the image in the sprite needs to be at least ~15px wide (with matching right/left padding).

Not sure the exact width, but I was getting the problem when I had button { padding: 0 10px 0 0; } and button span { padding: 0 0 0 10px; }

Hope that helps if someone else comes across the same issue.
Everything worked beautifully as soon as I increased the image width and bumped up the padding to button { padding: 0 15px 0 0; } and button span { padding: 0 0 0 15px; }

</div>
    <p class="posted"><a href="#commentNumber37">Comment</a> by

Karl Swedberg on 09/01  at  12:15 PM

<div id="commentNumber38" class="commentEntry">
<p>Help!

Am I the only one that experienced this 1 PX shift issue with IE 8 using this example?

I have my code working fine in all required browsers, except IE 8 due to this shift upon clicking my button.

I have searched high & low to no avail. Does anyone else have this problem and know of a way to solve this 1 PX shift in IE 8. My example is posted. All you need to do is rollover the button and press in IE 8 and look at the far right side shift upon click.

I really want to implement this solution for a project at work, but it won’t pass with the current IE 8 issue.

Any feedback would be greatly appreciated!

</div>
    <p class="posted"><a href="#commentNumber38">Comment</a> by

Tim Wilson on 09/01  at  12:54 PM

<div id="commentNumber39" class="commentEntry">
<p>I really want to implement this solution for a project at work, but it won’t pass with the current IE 8 issue.

</div>
    <p class="posted"><a href="#commentNumber39">Comment</a> by

منتديات on 09/05  at  10:31 PM

<div id="commentNumber40" class="commentEntry">
<p>I am seeing a 1 pixel shift on the right side of the button in IE8 and all looks well in Chrome.

</div>
    <p class="posted"><a href="#commentNumber40">Comment</a> by

مركز تحميل on 09/05  at  10:32 PM

<div id="commentNumber41" class="commentEntry">
<p>@Tim Wilson: The best option I’ve found to fix the 1px background shift in IE8 is using Microsoft’s CSS vendor extension (which work in IE8 but not previous versions). I’ve documented a solution here: <a href="http://bit.ly/NSd0b" rel="nofollow">http://bit.ly/NSd0b</a>.

</div>
    <p class="posted"><a href="#commentNumber41">Comment</a> by

Cory Duncan on 09/06  at  12:56 PM

<div id="commentNumber42" class="commentEntry">
<p>Small comment (als0o send via Mail):

If you klick on the Buttons in Opera and IE8 there is a browser-build-in
moving of the span/button of 1px to the lower left. I figured out a
solution for that and put it into my code:

// IE8 (via conditional comments put this into the code)
button:active {background-position: 100% 1px; position: relative; left:
1px; padding-left: 1px;}
button:active span {left: -1px;}

// Opera
button span:active {top: -1px; left: -1px;} /* Now, also Webkit moves
the button, so extend your hack: */
@media screen and (-webkit-min-device-pixel-ratio:0) { button span {
margin-top: -1px;} button span:active {top: 0px; left: 0px;}}

Regards,

Oliver

</div>
    <p class="posted"><a href="#commentNumber42">Comment</a> by

Oliver on 09/06  at  02:26 PM

<div id="commentNumber43" class="commentEntry">
<p>Thanks for the Article.

I’m guessing that there is still no fix for having this compatible for *readers who wish to browse with images off*

Do you know how i can overcome this?

Thanks
Jim

</div>
    <p class="posted"><a href="#commentNumber43">Comment</a> by

jim on 09/27  at  09:32 PM

<div id="commentNumber44" class="commentEntry">
<p>Hi-

Last year I finally released my button script called Simply Buttons.  I recently released v2, I think you guys might like what I have, some of my earlier experiments are eerily familiar to this technique.

http://www.p51labs.com/simply-buttons-v2/

Thanks,

Kevin

PS. Simple Buttons does have a fix for the “shifting pixel” as well ;)

</div>
    <p class="posted"><a href="#commentNumber44">Comment</a> by

Kevin Miller on 11/17  at  12:58 AM

<div id="commentNumber45" class="commentEntry">
<p>Extremely helpful article. I had read another Sliding Doors tutorial that used anchors instead of buttons and was scratching my head trying to figure out how to make IE play nice. The Safari/Chrome fix was helpful too!

Thanks again!

- Erich Musick

</div>
    <p class="posted"><a href="#commentNumber45">Comment</a> by

Erich Musick on 11/19  at  04:04 PM

<div id="commentNumber46" class="commentEntry">
<p>None of the above IE8 fixes seemed to work perfectly, but playing around I found that this combination works:

button.submitBtn:active {
-ms-background-position-y: [the ‘correct’ position - 1px] /*replace expression with value correct for your sprite */
}

button:active {
position: relative;
left:1px;
padding-left: 1px;
}

button:active span {
left: -1px;
}

So that’s working, but :active state not working for me in IE7.  Ideas?

Thanks!

</div>
    <p class="posted"><a href="#commentNumber46">Comment</a> by

Tim Sheiner on 12/02  at  03:37 PM

<div id="commentNumber47" class="commentEntry">
<p>Whoops, this declaration above:

button:active {
position: relative;
left:1px;
padding-left: 1px;
}

SHOULD BE

button:active {
position: relative;
left:1px;
}

</div>
    <p class="posted"><a href="#commentNumber47">Comment</a> by

Tim Sheiner on 12/02  at  03:40 PM

<div id="commentNumber48" class="commentEntry">
<p>And the answer to the IE7 :active issue:

The :active pseudo-class is most often used with the a element. Windows Internet Explorer 7 and earlier only support using the :active pseudo-class with the a element.

</div>
    <p class="posted"><a href="#commentNumber48">Comment</a> by

Tim Sheiner on 12/02  at  03:44 PM

<div id="commentNumber49" class="commentEntry">
<p>Please update the CSS in your article.

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

When it should be:
button::-moz-focus-inner {
padding: 0;
border: none; /* overrides extra padding in Firefox */
}

It appears you copied this incorrectly after the post from mstudio.  With the fix the buttons look good in Firefox 3.5.5

</div>
    <p class="posted"><a href="#commentNumber49">Comment</a> by

Richard Aday on 12/08  at  08:24 PM

<div id="commentNumber50" class="commentEntry">
<p>Hi, I have created a version of this and have found that it works well, accept for a spurious amount of padding between the two images in Webkit. I have compensated for this by increasing the width of the right hand image, the only downside to this is it means the text label no longer appears central to the button, I think your example produces the same result although it looks less pronounced than mine:

http://www.jeremydalgarno.com/images/buttons.png

You can see a corrected and uncorrected version and can see how the text is shifted. Do you think there is solution to this? We can remove this extra padding in IE and Mozilla but not currently in Webkit?

Thanks.

</div>
    <p class="posted"><a href="#commentNumber50">Comment</a> by

Jezz on 12/17  at  04:48 AM

<div id="commentNumber51" class="commentEntry">
<p>Hi

Tried this with a new Mac-look sprite. It looks wonderful in ALL browsers.
Congratz guys!

</div>
    <p class="posted"><a href="#commentNumber51">Comment</a> by

Yoke Lee on 01/08  at  03:10 AM

<div id="commentNumber52" class="commentEntry">
<p>Just a note, your CSS doesn’t have any “focus” or “active” states, so keyboard navigation is a bit hard to pick up (e.g. tabbing through the web page doesn’t actually highlight your sample buttons). Otherwise very nice work.

</div>
    <p class="posted"><a href="#commentNumber52">Comment</a> by

Xander on 01/10  at  11:41 PM

<div id="commentNumber53" class="commentEntry">
<p>So, when using the Safari/Chrome conditional below:

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

My code works fine and looks beautiful via DreamWeaver run locally, however when I upload my css to the server via Visual Studio 2010, the following code is no longer recognized or visible when using firebug in firefox to track down the problem.

Has anyone ever experieinced this issue with the Safari/Chrome hack?

Any help is greatly appreciated as I have exhausted all of my resources......

</div>
    <p class="posted"><a href="#commentNumber53">Comment</a> by

Tim Wilson on 01/12  at  02:47 PM

<div id="commentNumber54" class="commentEntry">
<p>re:

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

current versions of Safari(4.0.4 Mac) and Chrome do not need this, but looks like Safari(4.0.4 Win) does

anyone got a nice fix?

</div>
    <p class="posted"><a href="#commentNumber54">Comment</a> by

Jennie on 02/11  at  07:28 AM

<div id="commentNumber55" class="commentEntry">
<p>As a follow on, depending on your zoom level the two sides don’t always match up on the iPhone (but you could send css3 styling of -webkit-border-radius, -webkit-box-shadow and -webkit-gradient instead)

nice example over on 24ways for some ideas

</div>
    <p class="posted"><a href="#commentNumber55">Comment</a> by

Jennie on 02/16  at  07:20 AM

<div id="commentNumber56" class="commentEntry">
<p>Hey! i am facing a problem on this page in IE8   <a href="http://www.avtodeli.info/?c=user&amp;action=login" rel="nofollow">http://www.avtodeli.info/?c=user&amp;action=login</a>  you will se two buttons, expecaly the right one is tricky. And only IE8 is cousing a problem. Have any sollutions?&nbsp; ThX

</div>
    <p class="posted"><a href="#commentNumber56">Comment</a> by

Edvard on 02/18  at  05:40 AM

<div id="commentNumber57" class="commentEntry">
<p>Loving this concept, however…

although the buttons look consistent across browsers when the page is static, when you actually use the page and click the buttons you’l notice that internet explorer has an ‘on click’ effect on the <button> which makes it appear as if it is being pushed down. This effect makes the background images of the <span> and the <button> misalign and appear broken.

So my question is does anyone know of a method that would disable this ‘on click’ effect?

</div>
    <p class="posted"><a href="#commentNumber57">Comment</a> by

Philip Hillman on 03/02  at  08:42 AM

<div id="commentNumber58" class="commentEntry">
<p>I have found that in some cases,

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

needs to be

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

In order to prevent Firefox from adding an extra 2px left and right padding to the button element.

</div>
    <p class="posted"><a href="#commentNumber58">Comment</a> by

Greg Johnson on 03/04  at  12:29 PM

<div id="commentNumber59" class="commentEntry">
<p>This worked for me with Tim Sheiner’s second comment on 12/02

</div>
    <p class="posted"><a href="#commentNumber59">Comment</a> by

AL on 03/10  at  05:13 AM

<div id="commentNumber60" class="commentEntry">
<p>I would like to add an extra image to this so that the buttons can have an icon with the text.&nbsp; So far, I have manged to add an img tag inside the span, but the background sprite gets off by 12px on the enclosing tag (button here, I’m using an ‘A’ tag)  Has anyone manage this?

</div>
    <p class="posted"><a href="#commentNumber60">Comment</a> by

David Morton on 03/14  at  04:12 PM

<div id="commentNumber61" class="commentEntry">
<p>With the fix for IE and Opera it works perfektly for me! THX!!!!

</div>
    <p class="posted"><a href="#commentNumber61">Comment</a> by

Bravehartk2 on 03/17  at  10:05 AM

<div id="commentNumber62" class="commentEntry">
<p>Thank you for this fix.&nbsp; I would never have figured it out on my own....

Keep up the good work!

</div>
    <p class="posted"><a href="#commentNumber62">Comment</a> by

Corto on 03/30  at  08:03 AM

<div id="commentNumber63" class="commentEntry">
<p>thank you for share it

</div>
    <p class="posted"><a href="#commentNumber63">Comment</a> by

婚紗攝影 on 04/07  at  01:24 PM

<div id="commentNumber64" class="commentEntry">
<p>This worked for me and fixed the 1px difference between right and left ‘part of the button’ so far IE6 + IE7 + IE8 + FIREFOX + CHROME:

button:active {
-ms-background-position-y:-49px; (-correct position -1 :: height is 48px)
#bottom:0px;
_bottom:-1px;
}

</div>
    <p class="posted"><a href="#commentNumber64">Comment</a> by

Bart Calixto on 04/09  at  02:16 AM

<div id="commentNumber65" class="commentEntry">
<p>Thanks for the post. I found this in <a href="http://speckyboy.com/2009/05/27/22-css-button-styling-tutorials-and-techniques/" rel="nofollow">http://speckyboy.com/2009/05/27/22-css-button-styling-tutorials-and-techniques/</a> and used it for my project: <a href="http://food-prints.appspot.com/nutrients" rel="nofollow">http://food-prints.appspot.com/nutrients</a>. Besides making it smaller, I also added

button.submitBtn:active span {
line-height: 1em; /* push text down */
}

Thanks!

</div>
    <p class="posted"><a href="#commentNumber65">Comment</a> by

Sargis Dallakyan on 04/19  at  02:05 PM

<div id="commentNumber66" class="commentEntry">
<p>Thanks for the Chrome hack.

Although it makes me soo angry that we have to use hacks for every little thing in every browser. I want my time back!

</div>
    <p class="posted"><a href="#commentNumber66">Comment</a> by

Claudius on 04/27  at  08:15 AM

<div id="commentNumber67" class="commentEntry">
<p>Thanks Greg Johnson! That fixed the 2px padding issue I was having in firefox!

</div>
    <p class="posted"><a href="#commentNumber67">Comment</a> by

Matt Rittman on 05/17  at  09:49 AM

<div id="commentNumber68" class="commentEntry">
<p>maybe this will be good without javascript…

</div>
    <p class="posted"><a href="#commentNumber68">Comment</a> by

ryan on 06/08  at  01:35 AM

<div id="commentNumber69" class="commentEntry">
<p>Can anyone help me. I’ve created my own buttons and set them up using this technique, it’s great. How do I have them as an &lt;a&gt; instead of a button. I want the buttons to be links to navigate around a website. Please give me some advice or an example.

Thanks so much!

</div>
    <p class="posted"><a href="#commentNumber69">Comment</a> by

Darryl Young on 06/11  at  06:40 AM

<div id="commentNumber70" class="commentEntry">
<p>I am looking at your tutorial in IE8 on Windows 7 and the buttons exhibit the left/top 1px shift when clicked. I am running Windows 7 under Parallels/OS X but I don’t think that makes a difference.

</div>
    <p class="posted"><a href="#commentNumber70">Comment</a> by

werner on 06/23  at  07:49 PM

<div id="commentNumber71" class="commentEntry">
<p>From what I’ve checked it works very fine, except one problem - Safari 4 has exactly same problem that Firefox had - it adds 3px padding on the right side of a span element. It can be fixed using

button span {margin-right: -3px;}
in safari/chrome section. But since this bug applies ONLY to safari 4, as both safari 3 and chrome are ok, this causes span and button background to overlapin the later two browsers, which is would be more-less fine in case of gif/jpg, but when using semitransparent png’s, that overlapping is visible.

</div>
    <p class="posted"><a href="#commentNumber71">Comment</a> by

Viktoras on 07/02  at  05:33 AM

<div id="commentNumber72" class="commentEntry">
<p>thanks!

I’m on the way but that stupid margins in FF make me go crazy. That -moz-focus-inner invention is just silly.

again, thanks

</div>
    <p class="posted"><a href="#commentNumber72">Comment</a> by

MP on 07/23  at  03:24 AM

<div id="commentNumber73" class="commentEntry">
<p>Can any1 help me with my query??

background-image of a button is not getting displayed in IE8 for Win7

</div>
    <p class="posted"><a href="#commentNumber73">Comment</a> by

Kavita Modi on 08/02  at  05:28 AM

<div id="commentNumber74" class="commentEntry">
<p>just to follow up. I found that the left/top 1px shift only occurs when the submit button click is intercepted by jQuery. It doesn’t do it when IE8 is in IE7 mode.

</div>
    <p class="posted"><a href="#commentNumber74">Comment</a> by

werner on 08/03  at  08:16 PM

<div id="commentNumber75" class="commentEntry">
<p>I have managed to get these buttons working now in most situations but I was having the same problem a lot of you had in IE8 - when clicked (active) the ‘end piece’ of the image shifted slightly up and left. I’ve fixed this with “-ms-background-position” but I noticed a weird problem. If I click AND drag off the button, the ‘end piece’ shifts down and right slightly. This isn’t really a big problem, I just wondered why… :)

</div>
    <p class="posted"><a href="#commentNumber75">Comment</a> by

david on 08/18  at  05:16 AM

<div id="commentNumber76" class="commentEntry">
<p>1px IE8 problem can u help me plz?

</div>
    <p class="posted"><a href="#commentNumber76">Comment</a> by

yashpal on 08/19  at  02:17 AM

<div id="commentNumber77" class="commentEntry">
<p>i have 1px problem with IE8 and active problem with IE7 plz help me

Here is my css code

button {
position: relative;
outline:none;
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:bold 14px Arial, Helvetica, sans-serif;
text-align: center;
background: transparent url(btn_blue_sprite.gif) no-repeat right -162px;
}

button.submitBtn span {
padding:11px 0 0 15px;
height:25px;
background: transparent url(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 -216px;
}

button.submitBtn:hover span, button.submitBtnHover span {
background-position: 0 -55px;
}

button.submitBtn:active, button.submitBtnHover { /* the redundant class is used to apply the hover state with a script */
background-position: right -270px;
}

button.submitBtn:active span, button.submitBtnHover span {
background-position: 0 -108px;
}

</div>
    <p class="posted"><a href="#commentNumber77">Comment</a> by

yashpal on 08/19  at  02:20 AM

<div id="commentNumber78" class="commentEntry">
<p>Hi! Here’s another quick IE8 active fix: (You might have to modify the padding and the backgroundposition values so it fits your button size. Also, the outline declarations isn´t nessessary but it looks nicer. )

<!--[if IE 8]>
<style type="text/css">
button.submitBtn:active {padding-right:16px; -ms-background-position-y: -209px; outline:0 }
button.submitBtn:focus {outline:0 }
</style>
<![endif]-->

</div>
    <p class="posted"><a href="#commentNumber78">Comment</a> by

Jonas on 08/23  at  04:53 AM

<div id="commentNumber79" class="commentEntry">
<div id="commentNumber80" class="commentEntry">
<p>Has anyone fixed this for Safari 5 for Windows?

In the Safari media query, curiously Safari (5.0.2) for Windows also needs a margin-right: -3px to remove the right gap. However, that also causes an overlap on Safari 5.0.2 for Mac.

Anyone have any ideas?

</div>
    <p class="posted"><a href="#commentNumber80">Comment</a> by

Tim Kelty on 10/13  at  05:26 PM

<div id="commentNumber81" class="commentEntry">
<p>Hey,

Great work, but there is this tiny thing I would like to add. ( if it is not said yet.. )
To avoid IE7 “cut off” problems with letters like “g” ( for example “Log in” ),
then just use “line-height”. Give both “line-height” and “height” the same value, for example:

button.submitBtn span {
padding: 13px 0 0 15px;
height:37px;
line-height:37px;
}

Now you may need to play with the first (upper) padding to get the text in the center and also depends on what size is your font.

Good luck.

</div>
    <p class="posted"><a href="#commentNumber81">Comment</a> by

Henri on 11/29  at  02:02 PM

<div id="commentNumber82" class="commentEntry">
<p>nice really cool..

it’s most cool button i have ever used.

</div>
    <p class="posted"><a href="#commentNumber82">Comment</a> by

abhimanyu on 12/02  at  02:22 PM

<div id="commentNumber83" class="commentEntry">
<p>Even with the IE8 fix mentioned above, I am still noticing a 1px shift to the left on these buttons. The y-axis shift has been fixed, but not the x-axis shift. I think the reason is because the affected element is right aligned. I’ve tried several options, to no avail, with adjusting this right positioning. So I put in some IE8 conditional CSS and swapped the position of the background elements. I know this doesn’t work well in FF or Chrome, but it fixes the onClick/active shifts of the button element in IE8:

[[ CODE:

<!--[if IE 8]>

button.primary
{
padding: 0;
background: url( ‘/skins/ecommerce/resources/images/bg-button-2.gif’ ) no-repeat left top;
}

button.primary span
{
padding: 6px 15px 0 15px;
background: url( ‘/skins/ecommerce/resources/images/bg-button-2.gif’ ) no-repeat right -40px;
}

button.primary:active
{
-ms-background-position-x: 1px !important;
-ms-background-position-y: -79px !important;
}

button.primary:hover, button.primaryHover
{
background-position: left -80px;
}

button.primary:hover span, button.primaryHover span
{
background-position: right -120px;
}

<![endif]-->

However, I havent’ been able to find a fix yet for two remaining issues:

1. The button experiences a pixel shift in Chrome when you increase the page Zoom.
2. The button experiences a pixel shift in IE8 if, when you click on the button, you don’t release the mouse and drag in any direction.

Has anyone found a fix for these yet? Thanks!

</div>
    <p class="posted"><a href="#commentNumber83">Comment</a> by

Rob on 12/03  at  02:58 PM

<div id="commentNumber84" class="commentEntry">
<p>Is this still relevant information for how to create CSS sliding doors for buttons. I ask as i’m wanting to implement this into my website but not sure whether there is a new way to do this now. As i note this post is from 2009

</div>
    <p class="posted"><a href="#commentNumber84">Comment</a> by

Reclaim PPI on 12/29  at  06:01 PM

<div id="commentNumber85" class="commentEntry">
<p>You don’t actually need to separate the left button background and the right button cap image. You can just have a single long button and use it as the bg image. Saves some space on your sprite. :-)

</div>
    <p class="posted"><a href="#commentNumber85">Comment</a> by

Cre8ive Commando on 01/19  at  05:39 PM

<div id="commentNumber86" class="commentEntry">
<p>wow, good work need to take a look at this… I got a very interesting idea of this!

</div>
    <p class="posted"><a href="#commentNumber86">Comment</a> by

Fredrik on 01/21  at  04:55 AM

<div id="commentNumber87" class="commentEntry">
<p>This is really great. I am planning to use on all future clients if they’ll accept rollovers in their creative. Well done!

</div>
    <p class="posted"><a href="#commentNumber87">Comment</a> by

Neil on 02/15  at  01:33 PM

<div id="commentNumber88" class="commentEntry">
<p>Thanks for this great tutorial. Just what I was looking for :)

</div>
    <p class="posted"><a href="#commentNumber88">Comment</a> by

J. Hendrix on 03/18  at  07:52 AM

<div id="commentNumber89" class="commentEntry">
<p>This appears to have removed any action for when you click the mouse, or does this have to be manually implemented?

</div>
    <p class="posted"><a href="#commentNumber89">Comment</a> by

Dave on 03/31  at  10:59 AM

<div id="commentNumber90" class="commentEntry">
<p>Sorry, there was a bug in my previous comment:

The CSS for the webkit and opera fix should look like this:
/* fix webkit & opera */
.webkit button.button-light span,
.webkit button.button-dark span {
margin-top: -1px;
}

.opera button.button-light:active span,
.opera button.button-light span:active,
.opera button.button-light:active span:active {
left: -1px;
top: -1px;
}

But still there are two bugs mentioned in previous comments (hovering while not realeasing clicked button under IE8 and zooming under chrome) - but I guess we’ll have to live with that.

</div>
    <p class="posted"><a href="#commentNumber90">Comment</a> by

Tom on 05/21  at  05:23 AM

<div id="commentNumber91" class="commentEntry">
<p>The problem with your implementation is that a modern web UI must show multiple states.&nbsp; Your design does not have any way of showing a disabled state.

</div>
    <p class="posted"><a href="#commentNumber91">Comment</a> by

Simon Golding on 05/28  at  04:33 AM