A picture of me taking it easy

I'm currently on parental leave till September. During that time, I will not read any e-mail or blog comments.

Until I'm back, please read through my archives, take a look at my code/applications and check out my pictures.

Have a great summer, and a splendid winter to you aussies and kiwis! :-)

Can’t make links (appear ) clickable in IE

Published on Tuesday, January 22nd, 2008

We all know that Internet Explorer hasn’t been the best of the bunch rendering CSS properly, and while IE 7 got better, it’s far from perfect. I have an example here where I can’t make links (appear) clickable, no matter what.

The scenario

The scenario is easy and fairly common: I have a sidebar-navigation which will contain a number of images and interaction, so I need an extra element to hook into. My HTML code looks like this:

<ul>
	<li>
		<a href="/"><span>Da root</span></a>
	</li>
</ul>

And this is the CSS applied:

a {
	display: block;
}
span {
	display: block;
	height: 20px;
}

The problem

As long as the span has a specified height, or in any way gains hasLayout state (through float, height: 1%; or zoom: 1;), there will not be a cursor when you hover over it. Most of the times, though, it remains clickable and behaves like a link.

I tried any different hasLayout solution to this, adding background-color to the link since I know that solved similar problems in IE before, went crazy with position: relative, but nothing works!

Affected web browsers

This problem can be experienced in Internet Explorer 6 as well as Internet Explorer 7.

The challenge

Make this work! Show me that you’re smarter than me (hell, you have to be smart since you read this blog, right? :-) )!

Download the test file and play around with it, see if you have any idea why this happens and, more importantly, what to do about it.

Go!

 

PS. Suggestions adding cursor: pointer to the span element will be completely disregarded. :-) DS.

42 comments

  • trovster
    January 22nd, 2008 at 11:39

    Adding cursor: pointer; to the anchor works…

  • Silviu
    January 22nd, 2008 at 11:39

    Suggestions adding cursor: pointer to the span element will be completely disregarded

    How about adding that to the a. Works in IE7 for me.

  • Remy Sharp
    January 22nd, 2008 at 12:02

    Why do you need the span { display: block; } ?
    Removing that specific CSS style gives the entire link a pointer cursor again.

  • Harmen Janssen
    January 22nd, 2008 at 12:11

    It’s not possible to set height: 20px; on the anchor and height: 100% on the span?

    Weird stuff. I will be pondering about this a bit more today, let you know if anything springs to mind.

  • Robert Nyman - author
    January 22nd, 2008 at 12:16

    Remy,

    I need a height (actually a min-height) since it will contain a certain background image, so it has to cater for its height. For instance, display: block works fine on its own, it’s the height part which throws it off.

    Harmen,

    Nope, that doesn’t work.

  • Martin
    January 22nd, 2008 at 12:20

    Try using line-height instead of height on the span.

  • Maaike
    January 22nd, 2008 at 13:20

    Why not change the order in the HTML code a bit:
    <span><a href="/"> Da root</a></span>
    Or would you consider that cheating? ;-)

  • Peter Antonius
    January 22nd, 2008 at 13:26

    Add cursor:pointer to the span.

  • Maaike
    January 22nd, 2008 at 13:32

    … Or (cheating some more): use another element such as a div instead of a span. I think it’s just another obscure IE bug… somehow IE puts the span on top of the link instead of inside it.

  • Robert Nyman - author
    January 22nd, 2008 at 13:55

    Martin,

    That’s an option which will work in some cases, but not in others where the height has to match a certain image.

    Maaike,

    It feels a bit dirty, but it’s definitely the best solution I’ve sen so far. And, most of all, it works! Good thinking!
    (I also just got that suggestion over instant messaging)

    A div surrounding the link works, just like with span, but having a div within the link is invalid HTML (block element inside inline element).

    As stated many times before, comments with anonomous e-mail addresses will be removed.

  • Martin Odhelius
    January 22nd, 2008 at 14:00

    …use firefox ;)

    Sure, putting cursor:pointer on the <span> feels wrong cause its the link that is meant to trigger the pointer, not the span. But why not just put a cursor:pointer on the <a>-element? That will work in all browsers (even ie6 and ie7 ;)) I do not really see anything wrong with that, sure it is redundant in most browsers, but not wrong, and it is probably the clearest way to solve this… if you don’t like that workaround I rather think you shall ignore IE’s stupid default-behavior and just accept how it works, rather than to do a cryptic hack that will only solve a problem in one browser but just most likely make the solution more complex, hard to read and will absolutely not make any difference in any other browser… that was my 2 cents ;)

  • Maaike
    January 22nd, 2008 at 14:05

    A div surrounding the link works, just like with span, but having a div within the link is invalid HTML (block element inside inline element).

    Whoops… you’re right, of course. A <strong> or <em> would work though (except you might not want to emphasize every link).

  • Jeff L
    January 22nd, 2008 at 14:52

    I have to agree with the others here….

    Your markup is fine.
    IE has a bug.
    You have an awfully simple, VALID, CSS way around it.

    Just set the cursor type, either on the a or span element, and be done with it.

    Come on Robert…it’s not even a hack…

  • Lim Chee Aun
    January 22nd, 2008 at 14:59

    This is fun :D
    Another solution would be changing height: 20px; to line-height: 20px;

  • Robert Nyman - author
    January 22nd, 2008 at 15:14

    Martin Odhelius, Jeff L,

    Well, I agree that no one wants a complex work-around. That’s the whole idea, to find a solution to this without resorting to that. To me it’s far more interesting to find why it actually goes wrong, rather than just taking the easy route with a pointer cursor.

    The pointer would definitely be sufficient in this case, but the next time I might have almost the same mark-up, but the pointer won’t work then, I prefer learning some of the inner workings in IE now.

    A span encompassing the link, instead of vice versa, doesn’t seem more complex, and since they’re both inline elements, it’s totally valid.

    Lim,

    Line height wont work since the text in each item is completely wree to wrap, thus resulting in too high lines (and, more importantly, fixed line heights if I use the pixel unit instead of em).

    Right… Comments calling me an idiot will be removed too. If you can’t behave like a grown-up with respect, I’m not interested in your opinion.

  • Jeff L
    January 22nd, 2008 at 16:31

    Robert,

    I would think that in most cases, you’d likely have more control over the CSS than the markup. If the markup was being generated by a CMS, for instance, that you couldn’t modify.

    However, the link within the span versus another suggestion of a div within the link?
    Technically, yes, link and span are both inline elements so first solution is valid. But, you’re making the link a block level element, so a div within at that point should be valid as well (no, the validator doesn’t know this…but wouldn’t it be, when you think about it?)

  • Robert Nyman - author
    January 22nd, 2008 at 16:36

    Jeff,

    Absolutely, and I’ve thought about this for a while: if one turns an inline element into a block one, it should go by those rules.

    However, HTML validation has no CSS context, and semantically (some assistive technology, search engines etc) it’s incorrect. Tough call.

    I was hoping for some magic line of CSS rather than altering the HTML, so the problem would just disappear. So far, no luck.

  • Siegfried
    January 22nd, 2008 at 17:33

    Hi,
    maybe the problem is that within an anchor only inline elements are allowed. If you include a block element or an element redefined as block element this my confuse the browser.

    If you need to apply a hight why not try display: inline-block?

    If there wasn’t another problem with the IE, you could replace the span element with the button element (not the input element of type button, but the button element of type button). It is the only inline element which can be given a width and height per default. The problem with IE is, that it shows the link and shows the destination in the status line, but the link does not work. To partially solve this problem you could add a javascript event handler to the button repeating the link target. This works with all browsers, but with IE only if javascript is enabled.

  • Robert Nyman - author
    January 22nd, 2008 at 17:37

    Siegfrid,

    Good thinking with inline-block, but unfortunately it doesn’t work either. Taking the JavaScript route in any way here doesn’t sound like the best approach.

  • Siegfried
    January 22nd, 2008 at 18:06

    Agreed. And, BTW, on a button the cursor does not change, too i just discovered.

    So i do not know of any solution. The only thing imaginable would be to add the background image to the li element, not to the a element, forget that span and put a plain link into the li. You can set width and height to the li.

  • Robert Nyman - author
    January 22nd, 2008 at 19:52

    Siegfrid,

    Not an option either, since the LI will contain all child elements (ULs etc), and I only want one image on the links and one on the SPANs, as opposed to the LI where all children would then have that image.

  • Pablo Impallari
    January 22nd, 2008 at 22:33

    Quite easy challenge this one!

    Just add this to the span element:
    user-select: none;
    And remove the display declaration

    See it Here

    The problem is that the text inside the spam its selectable, so the proper cursor makes into the scene.
    By not alowing the user to select the text inside the spam, you no longer get the text cursor.

    Do I win something? :)

  • NICCAI
    January 22nd, 2008 at 23:07

    Are you sure you need the height? Can you not use padding instead? Could we see what you are trying to achieve?

  • Halans
    January 23rd, 2008 at 7:19

    How about:

    span {
    display: compact;
    height: 20px;
    }

    That seems to work in IE6 (not tested in IE7)

  • Robert Nyman - author
    January 23rd, 2008 at 9:05

    Pablo, Halans,

    The problem with your respective solutions it that the SPAN element doesn’t take the desired height into account. It displays a cursor, but it won’t respect the pixel height.

    Put a border, for instance, on the SPAN and you’ll see.

    NICCAI,

    Padding can definitely be a solution to some extent (and probably the one I’ll use in the real-case scenario that started this). but I want height to make sure that it matches the height of the background image.

    If I have padding, even if it’s set in pixels, the height of the SPAN will still depend on font-size of its text. hence if the user has a smaller font size, the SPAN won’t get the height I want.

  • Olivier G.
    January 23rd, 2008 at 10:02

    Strange. If i modify your CSS in :

    a {
    border: 1px solid blue;
    display: block;
    padding: 5px;
    }
    span {
    border: 1px solid red;
    display: block;
    height: 20px;
    }

    The cursor is not trigged over the padding part of the a.

  • Olivier G.
    January 23rd, 2008 at 10:05

    Fun, you have to add position: relative; to the a to get back the cursor on the padding space of the a.

    And giving a em element a hasLayout property triggers the incorrect behavior (try with an em element with zoom: 1).

  • Robert Nyman - author
    January 23rd, 2008 at 10:09

    Olivier,

    Yes, anything triggering hasLayout causes the error.

  • Olivier G.
    January 23rd, 2008 at 10:15

    a * {cursor: pointer;} works but will be disregarded ^^

    Can’t find a solution… :(

  • Anders
    January 23rd, 2008 at 10:20

    Jeff L:

    I believe that setting an elements display property to “block”, doesn’t really make it a block level element, but rather behave as one. Thus the document won’t validate. Am I wrong here?

  • Robert Nyman - author
    January 23rd, 2008 at 10:44

    Anders,

    Yes, and that’s the gist of it. Also, next time you comment, please provide a valid e-mail address. Anonymous comments (to me that is; anonymous to the public is just fine) will be removed.

  • Maxime Blaquiere
    February 27th, 2008 at 15:24

    I’m having the exact same problem, except that i have an img element inside the span. And because span’s displayed as a block, my image is not clickable.

    Still I can’t find a solution for this…!

  • Rick K
    February 27th, 2008 at 21:00

    < div style=”width:200px; height:100px;”>
    <a href=”#” style=”display:block; width:200px; height:100px”>
    words, images, whatever…
    </a>
    </div>

    seems to work for me.

  • Gary Hides
    March 11th, 2008 at 9:49

    You could use IE conditional statements to provide IE with different HTML.

    I’m stuck with the same problem and that’s the only thing I can think of at the minute.

  • Gary Hides
    March 11th, 2008 at 10:06

    My problem was in an online store part of a CMS wiwth images not being clickable in the span tag. So I have changed the product category template to not show the image using an img tag, but give the span which was removing the clickable area a background of the image in question, with no repeat.

    Then adding cursor: pointer; to the tag seems to work fine for me.

  • Robert Nyman - author
    March 12th, 2008 at 15:17

    Rick K,

    The problem is if you set a height on the element inside the link, or make it into a block. Then the problem occurs.

  • Eric
    March 29th, 2008 at 0:52

    Give this a shot:

    a {
    display: block;
    zoom: 1;
    }

    span {
    display: block;
    height: 20px;
    position: relative;
    z-index:-1
    }

    If you give the anchor layout and add the position and z-index to the span, it’ll move the span backward so it’s no longer a click-blocker. Haven’t tested much, but seems to work. (via brunildo)

  • Ellen
    March 29th, 2008 at 1:10

    Simply add a:link in front of the span tag. works in IE fine now.
    I’d seen in in a menu before where the a held one image and the span another image for menu buttons. This is how it is coded without the images

    a {
    display: block;
    }
    a:link span {
    display: block;
    height: 20px;
    }

  • Robert Nyman - author
    March 31st, 2008 at 9:31

    Eric,

    Great, that soultion works!

    Ellen,

    That’s even better! Fantastic, thank you!

  • Glook
    April 8th, 2008 at 12:47

    Ok, but what if in span not just text, but image ???

  • Ellen
    April 19th, 2008 at 6:23

    Yes it works with images in span too. I just tested it with his code above.
    < div id=”container”>
    <ul>
    <li><a href=”http://www.robertnyman.com/”>
    <span><img src=”file.jpg” alt=”pic”></span></a>
    </li>
    </ul>
    </div>

  • Peter
    July 11th, 2008 at 19:48

    Thanks,

    a{
    cursor:pointer
    }

    fixed it for me! Images that previously had the regular pointer now appear to be clickable in ie6.

    Cheers!

Share your thoughts:

HTML: You can use these tags: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <code> <em> <i> <strike> <strong> . If you want to display code examples, please remember to write &lt; for < and &gt; for >.

Comment preview

All the proceeds from ad clicks will go to charity. However, if you like to give something directly to charity yourself, I recommend choosing from the listed ones below.

  • Save the Children
  • Red Cross
  • Cancer Research UK
  • WWF

Top results