Can’t make links (appear ) clickable in IE

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.

53 Comments

  • trovster says:

    Adding cursor: pointer; to the anchor works…

  • Silviu says:

    <blockquote cite="Robert">Suggestions adding <code>cursor: pointer</code> to the span element will be completely disregarded

    How about adding that to the <code>a</code>. Works in IE7 for me.

  • Remy Sharp says:

    Why do you need the span { display: block; } ?

    Removing that specific css style gives the entire link a pointer cursor again.

  • It's not possible to set <code>height: 20px;</code> on the anchor and <code>height: 100%</code> 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 says:

    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, <code>display: block</code> works fine on its own, it's the height part which throws it off.

    Harmen,

    Nope, that doesn't work.

  • Martin says:

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

  • Maaike says:

    Why not change the order in the html code a bit:

    <code><span> Da root</span></code>

    Or would you consider that cheating? πŸ˜‰

  • Add cursor:pointer to the span.

  • Maaike says:

    … 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 says:

    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 <code>div</code> surrounding the link works, just like with <code>span</code>, but having a <code>div</code> 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 says:

    …use firefox πŸ˜‰

    Sure, putting <code>cursor:pointer</code> on the <code><span></code> feels wrong cause its the link that is meant to trigger the pointer, not the span. But why not just put a <code>cursor:pointer</code> on the <code><a></code>-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 says:

    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 or would work though (except you might not want to emphasize every link).

  • Jeff L says:

    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 says:

    This is fun πŸ˜€

    Another solution would be changing <code>height: 20px;</code> to <code>line-height: 20px;</code>

  • Robert Nyman says:

    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 <code>em</code>).

    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 says:

    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 says:

    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 says:

    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 says:

    Siegfrid,

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

  • Siegfried says:

    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 says:

    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.

  • 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 says:

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

  • Halans says:

    How about:

    span {

    display: compact;

    height: 20px;

    }

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

  • Robert Nyman says:

    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. says:

    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. says:

    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 says:

    Olivier,

    Yes, anything triggering hasLayout causes the error.

  • Olivier G. says:

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

    Can't find a solution… πŸ™

  • Anders says:

    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 says:

    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 says:

    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 says:

    < div style="width:200px; height:100px;">

    words, images, whatever…

    </div>

    seems to work for me.

  • Gary Hides says:

    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 says:

    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 <a> tag seems to work fine for me.

  • Robert Nyman says:

    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 says:

    Give this a shot:

    <code>

    a {

    display: block;

    zoom: 1;

    }

    span {

    display: block;

    height: 20px;

    position: relative;

    z-index:-1

    }

    </code>

    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 says:

    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 says:

    Eric,

    Great, that soultion works!

    Ellen,

    That's <code>even</code> better! Fantastic, thank you!

  • Glook says:

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

  • Ellen says:

    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 says:

    Thanks,

    a{

    cursor:pointer

    }

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

    Cheers!

  • Kris says:

    I've run into a similar problem with my site (just a template). I know what is causing it — I have a negative margin on the closure block which is covering up the footer block where I have my bottom row of links that aren't clickable in IE. I've went through the suggestions in this thread and can't get anything to work. Does anyone have any suggestions on how to get my links in the footer to work?

    http://kris.dreamhosters.com/mhw/

  • Robert Nyman says:

    Kris,

    Off the top of my head, sorry, I have no good suggestion.

  • Kris says:

    I ended up figuring it out! I created an inner div in closure, put the attributes there plus a width of 200px so the div doesn't cover the links in the footer. I came up with that late last night (late being a relative word, I'm a morning person) and upon further thought, I probably could have done that without the extra markup, namely just added the width to the closure. What do you think?

    Also, my link isn't updated with the change.

  • Robert Nyman says:

    Kris,

    Whatever works for you, go crazy! πŸ™‚

  • Aram Dermenjian says:

    So I'm running into a similar problem in IE7 except that not only will the cursor not display, but the link won't work either. Here is how I have it set up:

    HTML:

    <a > <span > <img /> <img /> < /span > < /a >

    CSS:

    a {}

    a span {width:100px; height:100px; overflow:hidden}

    a span img {display:inline; border:0; text-align:center;}

    How do you overcome this IE bug?

    I tried the following with no success:

    -changing the z-index to -1 to push it back

    -changing the display of span to: block, inline, inline-block (none with success)

    Oddly, the a works around the span, but is not clickable/linkable within the span.

    Any recommendations would be helpful!

  • I just spend half a day trying to solve this problem. Bruno also suggests the <code>z-index: -1</code> method at http://www.brunildo.org/test/IEaL.html

    Unfortunately, in my particular scenario this did not solve the problem — even though it did solve my problem in my stripped down test case.

    I figured out that it will work if IE sees a non-default value for the <code>background</code> property. Considering the negative z-index, it is not possible to use a background color. Instead I opted to use a non-repeating background image that is positioned outside of the box.

    See the diff and test case at http://pastebin.com/pastebin.php?diff=f69681142

  • Robert Nyman says:

    Jeroen,

    Great, thanks for sharing!

  • […] can’t make links appear clickable in IE not clickable image in a link css tests and experiments […]

  • sneha says:

    sir,

    I have a radio button list..

    I had to display images and text using it.

    I am using

    table.mylist input

    {

    float: left;

    border : none;

    height: 80px;

    margin-bottom :-20px;

    text-align: center;

    display: none;

    }

    table.mylist label

    {

    width: 70px;

    display: block;

    float: left;

    text-align: center;

    margin: 0px 25px 0px 25px;

    height: 70px;

    }

    and

    radiobuttonlist.Items[i].Text = " " + "" + rbl.Items[rblActualCount].Text; //

    I am hiding the radio button using ( display:none ) and when i click on the button, i am changing the color of btton to green.

    Everything is workling fine firefox, safari, google chrome…. but not working in IE…

    Can u please help me out???

  • Robert Nyman says:

    sneha,

    I'm sorry, I can't see in your example why it wouldn't work.

    Also, this: <code>radiobuttonlist.Items[i].Text = ” ” + “” + rbl.Items[rblActualCount].Text; // </code> – I guess it some .NET code or something? Either way, that's not relevant to this.

  • The VGcool says:

    here is the thing that worked for me.
    just right click you html file, go to properties and in the general menu
    you would see something like ” this file come from…..” and a button saying
    “unblock” just click on it , apply it and you are done !
    this is the thing that worked for me !!

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.