hasLayout.net

Image Label Focus Bug

Affected Versions

This bug affects: IE8, IE7

Symptoms

<img> elements that are inside <label> elements, when clicked, do not cause the focus to be transfered to corresponding form control.

Date of the Tutorial

Wed Aug 19 15:38:47 2009

Description

I found this bug on Gérard Talbot's IE8 Bug Collection Page and credit for it goes to Batiste Bieler. I had pleasure personally experiencing this bug some time ago on a site that I was making... not fun. Let's have a look:

Demo

The demo is available on a separate page

HTML Code:
<form action="">
<ul>
    <li>
        <label for="one"><img src="hl_logo.png" alt=""></label>
        <input type="text" id="one">
    </li>
    <li>
        <label for="two"><img src="hl_logo.png" alt=""></label>
        <textarea cols="10" rows="3" id="two"></textarea>
    </li>
    <li>
        <label for="three"><img src="hl_logo.png" alt=""></label>
        <input type="checkbox" id="three">
    </li>
    <li>
        <label for="four"><img src="hl_logo.png" alt=""></label>
        <input type="radio" name="foo" id="four">
    </li>
    <li>
        <label for="five"><img src="hl_logo.png" alt=""></label>
        <input type="radio" name="foo" id="five">
    </li>
</ul>
</div>
CSS Code:
li {
    overflow: hidden;
    display: inline-block; /* gives layout for IE float clearing */
}
li { display: block; }
label {
    float: left;
}

The demo is so large only because it's closer to the "real life" code of the ' element"><form> and this fact will make it easier for me to show the CMS solution for this bug.

The nature of the bug is that when ' element"><img> elements inside ' element"><label> elements are clicked they do not cause the focus to be assigned to corresponding form controls as it happens with plain text and there are no triggers - the behaviour is constant.

Solutions

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

Solution (Clean Markup Solution)

Date of the Solution

Wed Aug 19 15:39:12 2009

Fixed Versions

All of the affected

Description

Since ' element"><img> elements are the problem, this fix will involve covering them up with a ' element"><span>, let's have a look at the fixed demo:

Fixed demo is available on a separate page

HTML Code:
<form action="">
<ul>
    <li>
        <label for="one"><span></span><img src="hl_logo.png" alt=""></label>
        <input type="text" id="one">
    </li>
    <li>
        <label for="two"><span></span><img src="hl_logo.png" alt=""></label>
        <textarea cols="10" rows="3" id="two"></textarea>
    </li>
    <li>
        <label for="three"><span></span><img src="hl_logo.png" alt=""></label>
        <input type="checkbox" id="three">
    </li>
    <li>
        <label for="four"><span></span><img src="hl_logo.png" alt=""></label>
        <input type="radio" name="foo" id="four">
    </li>
    <li>
        <label for="five"><span></span><img src="hl_logo.png" alt=""></label>
        <input type="radio" name="foo" id="five">
    </li>
</ul>
</div>
CSS Code:
li {
    overflow: hidden;
    display: inline-block; /* gives layout for IE float clearing */
}
li { display: block; }
label {
    float: left;
    position: relative;
    overflow: hidden;
}
label span {
    position: absolute;
    left: 0;
    top: 0;
    width: 500px;
    height: 500px;
    background: url(hl_logo.png) no-repeat -5000px; /* required for IE click bug fix */
}

What I did here is insert an empty ' element"><span> element inside every ' element"><label> with an ' element"><img> and then I've set {position: relative;} on the ' element"><label>s for our offsets on ' element"><span>s - that I've made absolutely positioned - to be relative to the ' element"><label>s. I've set top and left to ensure that weird offsets do not occur in older IEs and I've set height and width to be large enough to surely cover the entire ' element"><img> element. I've set { overflow: hidden; } on our ' element"><label>s to hide excess width/height of the ' element"><span>s and since our ' element"><label>s are floated I did not have to set explit dimensions on them.

Now, the juicy part with the background set on the ' element"><span>s: this is a fix for the bug that manifested itself in IE; I believe its related to "Partial Click Bug v2". The problem is that our ' element"><span>s need transparent background on them set for the image to show through them, yet they need to have a non-transparent background for the bug not to occur (the bug is that clickety on the span "falls through" to the image). What I did to fix that is I've set the image that we are already using in ' element"><img> elements - because it would be cached - as background and offset it outside the view; the image can be anything you want, and you can even specify background: url(#); or background: url(your_css_file.css); - if all that feels dirty, you can simply create a transparent GIF image and set it as background.

The fix is in place and now are ' element"><img>s are clickable in all the affected IEs \o/