Using Images as Labels in Internet Explorer
Internet Explorer has a bug where wrapping a label around an image doesn't work the same as if you wrap it around text.
Example:
<input type="checkbox" id="a"><label for="a"><img src="..."></label>
What the label
does is create an association between its contents and a control on the page. In most browsers, clicking on text or an image within the label will give focus to the area. In the case of a radio button, it will select it and in the case of a checkbox, it'll alternate between the two states (checked and unchecked).
Internet Explorer, however, has a bug where clicking on an image inside a label tag does nothing. (Actually, I should say nothing useful because with radio buttons and checkboxes it looks like it tries to select the control but never does.)
What I've done is put together a quick bit of unobtrusive JavaScript to "fix" the problem. Albeit, only for people with JavaScript turned on.
window.onload = function(){
if(document.all && navigator.appVersion.indexOf("MSIE")>-1 && navigator.appVersion.indexOf("Windows")>-1)
{
var a = document.getElementsByTagName("label");
for(var i=0,j=a.length;i<j;i++){
if(a[i].hasChildNodes && a[i].childNodes.item(0).tagName == "IMG")
{
a[i].childNodes.item(0).forid = a[i].htmlFor;
a[i].childNodes.item(0).onclick = function(){
var e = document.getElementById(this.forid);
switch(e.type){
case "radio": e.checked|=1;break;
case "checkbox": e.checked=!e.checked;break;
case "text": case "password": case "textarea": e.focus(); break;
}
}
}
}
}
}
What the code does is loop through all labels on the page and checks whether the first child node is an image [1]. If it is then it attaches an onclick
event handler which when run, checks to see what type of form control it's attached to and performs the expected action.
[1] While I don't have a specific need for it, it is theoretically possible to have the image not be the first child node within the label. The code would need to be expanded to locate where and how many images are inside a label and assign the event handler that way.
One additional caveat, this code would theoretically override any existing onclick event handler, so best to think about all the scenarios and plan!
Update on November 21, 2010: A jQuery solution provided by Eli Penner.
$("label img").live("click", function() {
$("#" + $(this).parents("label").attr("for")).click();
});
Update on November 22, 2015: A CSS solution for IE11.
label img{
pointer-events: none;
}
label{
display: inline-block;
}
The inline-block
ensures that the image gets wrapped properly so that it can be clicked on.
(Thanks to Saulius Žemaitaitis for letting me know about this.)
Conversation
Just the other day I noticed this bug, and here's a solution. How did you know? ;-)
I was reading the other day about being able to click on the labels (textual) of checkboxes to make a selection. I haven't found the javascript for it yet, but I know it's out there. http://pingomatic.com/ < there is a site that uses it...
Actually, for text-based labels, there's no javascript necessary. IE supports them correctly. All you need to do is specify the id of the input that the label belongs to. (like in the example I gave but instead of an image, it's text). The javascript is intended only to fix a bug in IE.
Nice fix. I've slightly modified your code to allow more than one image to be in the label.
Changed the code in the IF statement to:
a[i].onclick = function(){
var e = document.getElementById(this.htmlFor);
switch(e.type){
case "radio": e.checked|=1;break;
case "checkbox": e.checked=!e.checked;break;
case "text": case "password": case "textarea": e.focus(); break;
}
This adds the onclick event to the LABEL itself, which seems to work very well in IE.
http://www.snook.ca/archives/javascript/using_images_as/
AWESOME Code! Thank you
Hi, I came up with CSS workaround for this bug - you can watch the demo because frankly, I don't think you understand Polish. ;-)
Best regards.
Nice trick, seems to work very well in IE7.
Many thanks! My need for an IE fix is very specific so I just use addEvent in-page, but this helped me confirm it wasn't my HTML or some other specific conflict, just another IE wonkyism.
hi,
You have done a good job. I am facing this problem and I got solution by this. So I am thankful to you. So keep doing such work.
Excellent solution, thanks a lot!
I liked it... But it needs a little modification to fire onclick events of a checkbox, select, or text input. Here is my patched version of this script snipt that need to be modified:
Best Regards
The Prototype solution :
Event.observe(window, 'load', function() {
if (Prototype.Browser.IE) {
var imgLabels = $$("label img");
imgLabels.each(function(eachImgLabel) {
Event.observe(eachImgLabel, "click", function() {
var radiolabel = eachImgLabel.ancestors()[0].readAttribute('for');
$(radiolabel).click();
});
});
}
});