hasLayout.net

Button Background Shift On :active Bug

Affected Versions

This bug affects: IE8

Symptoms

Background shifts up and to the left on :active state when applied to <button> or <input type="submit">

Date of the Tutorial

Thu Aug 13 18:19:22 2009

Description

Despite the fact that CSS spec states that CSS 2.1 does not define which properties apply to form controls and frames, or how CSS can be used to style them. User agents may apply CSS properties to these elements. Authors are recommended to treat such support as experimental (CSS2.1 Section 3.2 - UA Conformance) I would like to agree with the author of the page where I found the bug that this is in fact a bug. To the demo!

Demo

The demo is available on a separate page

HTML Code:
<button>Click me</button>
<form action="" method="GET" onsubmit="return false;">
<div>
    <input type="submit" value="Click me">
</div>
</form>
CSS Code:
input, button {
    background: url(button.png);
    border: 0;
    display: block;
    height: 30px;
    width: 81px;
    text-indent: -10000px;
    overflow: hidden;
}
input:hover, button:hover { 
    background-position: 0 -30px;
}

IE8 tries to be "smart" over here and shifts the background on :active to stupidly emulate the "button-press" effect. What I mean is that the background shifts up and to the left a bit when you click on either ' element"><button> or submit type of ' element"><input>.

Solutions

Below are solutions for the above bug ordered by the solution type.

Solution (Conditional Comments Solutions) - with Side Effects

Date of the Solution

Thu Aug 13 18:40:49 2009

Fixed Versions

All of the affected

Description

Fight fire with fire. We're going to fix this bug by changing the background-position on the :active state specifically for IE8. Let's have a look:

Fixed demo is available on a separate page

HTML Code:
<button>Click me</button>
<form action="" method="GET" onsubmit="return false;">
<div>
    <input type="submit" value="Click me">
</div>
</form>
CSS Code:
input, button {
    background: url(button.png);
    border: 0;
    display: block;
    height: 30px;
    width: 81px;
    text-indent: -10000px;
    overflow: hidden;
}
input:hover, button:hover { 
    background-position: 0 -30px;
}
Conditional Comments Code:
<style type="text/css">
        input:active, button:active {
        background-position: 1px -29px;
        /*
            If you are using one sheet for all
            the IEs you can specify:
                -ms-background-position-x: 1px;
                -ms-background-position-y: -29px;
            instead
        */
    }
</style>

The background on :active shifts by two pixels in each direction. Our IE8-targeted offset would be 1 pixel more to the right and 1 pixel more towards the bottom in comparison to your original offset for :hover (or normal state), thus, in our demo the background-position becomes 1px -29px.

If you are like me and prefer to use one sheet for all of the IEs (or you want to stick the fix in your regular sheet) simply use -ms-background-position-x: 1px; -ms-background-position-y: -29px; on the :active state.

Side Effects

The side effect of this solution is that if the user clicks the button and then moves the mouse away from the button or double clicks the button the background movement can still be seen. Since this is would rarely happen, I think you shouldn't worry about it. The page on which I found the bug also lists a markup solution that (I would assume) does not suffer from this side effect; however, since it's not applicable to the <input type="submit"> I will not include it on this page.