7

It seems IE doesn't care for text-decoration: none; defined for a:before pseudo element (or pseudo class).

Here is a JS Fiddle: http://jsfiddle.net/9N35f/
I'd expect the ">" to lose the underline. It does in FF, Chrome and Safari, but not in IE. Tested with IE10 and IE9.

The question:

Any workarounds that I could try to make the :before element lose the underline? Ideally in IE9+

Is there a bug report for this somewhere? Or is it actually by the standards?

frnhr
  • 12,354
  • 9
  • 63
  • 90
  • [Pseudo-element !== pseudo-class](http://stackoverflow.com/questions/8069973/what-is-the-difference-between-a-pseudo-class-and-a-pseudo-element-in-css) – laggingreflex Feb 15 '15 at 18:30

6 Answers6

8

I'm aware this is a rather elderly thread, but having just been up against this problem in IE 11, and unable to find much help, I decided to experiment. Aided by a significantly improved dev tools than in the earlier versions I managed to figure it out - for what I'm working on at any rate. Chances are it'll work for others as well, although you might need to tweak. YMMV.

The HTML:

<li><a href="#">Whatever</a></li>

The CSS (edited after @frnhr pointed out that the initial version I posted didn't actually work):

a {
    display: block;
    position: relative;
    padding-left: 15px;
    text-decoration: none;
}

a:hover {
    text-decoration: underline;
}

a:before {
    position: absolute;
    left: 0;
    top: 0;
    height: calc(100% - 2px);

    overflow: hidden;

    content: ">";
}

The secret sauce is setting the height and the overflow: hidden; line; it means that the underline is still there but outside the viewport provided by pseudo element, and so never gets seen on screen. It also works across other browsers (tested on Chrome and Firefox as well). Depending on your existing styling you'll probably want to tweak the pixel value in the calc() value.

See http://jsbin.com/biwomewebo/1/edit?html,css,output

Irregular Shed
  • 163
  • 3
  • 6
  • Doesn't work for me. Tried in IE11 Win8.1, here is a JSBin: http://jsbin.com/qetomizase/1/edit?html,css,output Can you make it work in a JSBin? – frnhr Apr 14 '15 at 11:51
  • Rats! I was converting from less to CSS for brevity (this is part of an ongoing project) and clearly have something missing. I'll spin up a VM and try again. – Irregular Shed Apr 14 '15 at 16:58
  • +1 This works now! Note that some letters and special chars will be cut off at the bottom: `y, g, j, µ, |, {, [, ▼` etc. – frnhr Apr 15 '15 at 09:57
  • I think with some experimentation with line height, etc you might be able to work around that. I've not had the chance - on the site I'm working on we're using an icon font to provide an indicator before the link, and for purposes like that this is a perfect fix :) – Irregular Shed Apr 15 '15 at 11:09
  • 1
    It is a good hack, and thank you for it! It will surely be usable. I was just noting the issue with cutting off the low-hanging letters. I haven't need able to find a fix for it, tried `line-height`, `padding`, `margin`, etc. What *might* work is some funky combination of `display: table-cell` and `display: table` on parent a element, along with `vertical-align: top`, but just maybe... – frnhr Apr 15 '15 at 11:37
5

IE seems to be in error here, since display: block in your code should remove the underlining. According to clause 16.3 Decoration in the CSS 2.1 spec, “User agents must not render these text decorations on content that is not text. For example, images and inline blocks must not be underlined.”

There does not seem to a bug a report on this at the IE Feedback Home.

In this case, a suitable workaround might be to use an image as the generated content:

a:before {
    content: url(arrow.png);
}

where arrow.png refers to a suitable small icon. The use of url(...) in content is described in CSS3 Generated and Replaced Content Module, which is a seriously outdated draft (the last version is from 2003), but this part has been widely implemented in browsers. Not in IE 7, however. So if you wish to cover IE 7 as well, consider the approach in @EugeneXA’s answer, possibly generating the extra markup dynamically with JavaScript.

Jukka K. Korpela
  • 195,524
  • 37
  • 270
  • 390
3

If the background is white you may use the bottom border:

a {
    text-decoration: none;
    border-bottom:1px solid blue;
}

a:before {
    content: "> ";
    border-bottom:1px solid white;
}
nico
  • 837
  • 5
  • 4
2

Not sure what standards say, but IE behavior seems to be more logical. Think of :before as an element inside of <a> tag, not outside of it. Child's text-decoration property should have nothing to do with its parent's.

This workaround will work

http://jsfiddle.net/9N35f/4/

<span><a href="#">a link</a></span>

a {
    text-decoration: underline;
}

span:before {
    content: ">";
}
Evgeny
  • 6,261
  • 8
  • 35
  • 43
  • +1 True, but that complicates things, I'd like to do that without adding an extra element. Think tinyMCE editor and applying a class to `` to make it look different. – frnhr Aug 05 '13 at 23:27
  • I think this explains why it (should be) impossible: http://stackoverflow.com/questions/4481318/css-text-decoration-property-cannot-be-overridden-by-child-element/4481356 – Evgeny Aug 05 '13 at 23:43
  • I was afraid of something like that. The `display: inline-block;` seems to play some role in other browsers. – frnhr Aug 05 '13 at 23:49
2

Another solution is to set a small line-height (heightdoes work too) and set overflow: hidden so the underline disappears.

I know this is not the best solution, because the line-height value depends on the character you use. In this case 0.6 is a good value but maybe not for another character.

In my case it was a good solution because I had the problem with only one certain character with a fixed font-size.

a {
    text-decoration: underline;
}

a:before {
    content: ">";
    display: inline-block;
    text-decoration: underline; /* simulate IE behavior */
    line-height: 0.6; /* line-height must be smaller than font-size */
    overflow: hidden;
}

JSFiddle Demo

KevinH
  • 1,066
  • 1
  • 14
  • 17
  • 1
    This works, but be aware that characters like "j", "g", "y" and "q",will get their lower part cut off. Which is not a problem for the ">" though :) – frnhr Aug 26 '15 at 18:01
1

This works for me:

html:

<a href="#"><span>a link</span></a>

css:

a {
  text-decoration: none;
}
a span {
  text-decoration: underline;
}
a:before {
  content: ">";
}

In this the before tag is still part of the anchor.

Martin
  • 11
  • 2
  • We all can make rocket ships by adding new HTML elements :) The trick is to do so without changing HTML structure. Why? Oh, I'd love to change the HTML structure, but unfortunately, in this case It's out of my hands. It's generated by a third party JavaScript library blah blah... – frnhr Oct 21 '13 at 14:49