hasLayout.net

IE7 "Broken" :hover Absolute Bug

Affected Versions

This bug affects: IE7

Symptoms

:hover that changes left/top offsets of an absolutely positioned descendant does not appear to "work" if the element is hidden out of the view; if it's visible, the left/top offsets do not change on :hover

Date of the Tutorial

Fri Aug 14 14:53:45 2009

Description

Here's another bug I found on Gérard Talbot's IE7 Bug Collection Page. The reason I put "Broken" in quotes in the title of the bug is because at first it may appear as if :hover is ignored; however, the actual reason is that left/top properties are not being changed on as can be seen in the second ' element"><div> in the demo. Let's have a look:

Demo

HTML Code:
<div class="container">
    CAN HAS HOVERS?!
    <p id="hidden">
        I AM HIDDEN ABSOLUTE!!!
    </p>
</div>
<div class="container">
    CAN HAS HOVERS?!
    <p id="visible">
        I AM VISIBLE ABSOLUTE!!!
    </p>
</div>
CSS Code:
.container {
    background: #ddd;
    border: 2px solid #000;
    padding: 5px;
    width: 500px;
    height: 100px;
    margin: 20px auto;
    position: relative;
}
#hidden,
#visible {
    background: #0f0;
    position: absolute;
    border: 2px solid #f00;
}
#hidden {
     top: -10000px; 
     left: 0; 
}
#visible {
    left: -100px;
    top: 0;
}
.container:hover #hidden {
    top: 0;
}
.container:hover #visible {
    left: 0;
}

When :hovering the ' element"><div>s in IE7 the ' element"><p>s will not move to be fully inside the surrounding ' element"><div>s as is the case in sane browsers.

Whilst the demo is quite large, is it only because I shown all four "cases" of the bug, i.e. top/left as well as fully hidden and visible absolutely positioned elements.

There doesn't seem to be any special triggers, all that is needed is top/left offsets to be set on non-hover state to anything but percentage values and them being changed on :hover (again to anything but percetange values).

Solutions

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

Solution (Clean Solution)

Date of the Solution

Fri Aug 14 15:19:52 2009

Fixed Versions

All of the affected

Description

The solution to the bug, aside from using percentage values for left/top, can also be margin. Let's have a look at the fixed demo first:

HTML Code:
<div class="container">
    CAN HAS HOVERS?!
    <p id="hidden">
        I AM HIDDEN ABSOLUTE!!!
    </p>
</div>
<div class="container">
    CAN HAS HOVERS?!
    <p id="visible">
        I AM VISIBLE ABSOLUTE!!!
    </p>
</div>
CSS Code:
.container {
    background: #ddd;
    border: 2px solid #000;
    padding: 5px;
    width: 500px;
    height: 100px;
    margin: 20px auto;
    position: relative;
}
#hidden,
#visible {
    background: #0f0;
    position: absolute;
    border: 2px solid #f00;
}
#hidden {
     top: -10000px; 
     left: 0; 
}
#visible {
    left: -100px;
    top: 0;
}
.container:hover #hidden {
    top: 0;
    margin-left: 0%;
    /* can use any direction
        or set to value other than 0
    */
}
.container:hover #visible {
    left: 0;
    margin-left: 0%;
    /* can use any direction
        or set to value other than 0
    */
}

What I did is set margin-left property to value 0% - note that the percentage unit here is important; even though setting to simply 0 would have the same effect, omiting the percentage unit will not fix the bug. Alternatively, you can set margin in any direction to any value other than zero with any unit.