103

I have a set of styled links using the :before to apply an arrow.

It looks good in all browser, but when I apply the underline to the link, I don't want to have underline on the :before part (the arrow).

See jsfiddle for example: http://jsfiddle.net/r42e5/1/

Is it possible to remove this? The test-style I sat with #test p a:hover:before does get applied (according to Firebug), but the underline is still there.

Any way to avoid this?

#test {
  color: #B2B2B2;
}

#test p a {
  color: #B2B2B2;
  text-decoration: none;
}

#test p a:hover {
  text-decoration: underline;
}

#test p a:before {
  color: #B2B2B2;
  content: "► ";
  text-decoration: none;
}

#test p a:hover:before {
  text-decoration: none;
}
<div id="test">
  <p><a href="#">A link</a></p>
  <p><a href="#">Another link</a></p>
</div>
Michael Benjamin
  • 265,915
  • 79
  • 461
  • 583
OptimusCrime
  • 13,936
  • 12
  • 52
  • 91
  • Well, you obviously want a list... Use an UL element instead of the DIV/P combination. With lists you get the bullets (or discs, ... ) for free... – Šime Vidas Jan 11 '12 at 13:49
  • Why not to use list with custom bullets instead of paragraphs in your case? Otherwise apply before-content to parent p, not to link itself. – YuS Jan 11 '12 at 13:50
  • Possible duplicate of http://stackoverflow.com/questions/8536015/before-on-link-stop-before-content-being-underlined-on-hover/17346595#17346595 – Oriol Jun 27 '13 at 15:20

6 Answers6

184

Is it possible to remove this?

Yes, if you change the display style of the inline element from display:inline (the default) to display:inline-block:

#test p a:before {
    color: #B2B2B2;
    content: "► ";
    display:inline-block;
}

This is because the CSS specs say:

When specified on or propagated to an inline element, it affects all the boxes generated by that element, and is further propagated to any in-flow block-level boxes that split the inline (see section 9.2.1.1). […] For all other elements it is propagated to any in-flow children. Note that text decorations are not propagated to floating and absolutely positioned descendants, nor to the contents of atomic inline-level descendants such as inline blocks and inline tables.

(Emphasis mine.)

Demo: http://jsfiddle.net/r42e5/10/

Thanks to @Oriol for providing the workaround that prompted me to check the specs and see that the workaround is legal.

Phrogz
  • 271,922
  • 98
  • 616
  • 693
  • 2
    You can override a `text-decoration:underline` applied to a parent element with `display:inline-block`. See an example: http://jsfiddle.net/aZdhN/1/ . Then, asker's problem can be solved like this: http://stackoverflow.com/a/17347068/1529630 – Oriol Jun 27 '13 at 15:31
  • 3
    As far as I can see, this does not work in Internet Explorer (tested 8-10). Any ideas how to deal with IE? – Linus Caldwell Oct 17 '13 at 17:08
  • I've found a solution that is working in IE8-11 too: http://stackoverflow.com/a/21902566/1607968 – LeJared Feb 20 '14 at 08:50
54

There is a Bug in IE8-11, so using display:inline-block; alone won't work there.

I've found a solution for this bug, by explicitly setting text-decoration:underline; for the :before-content and then overwrite this rule again with text-decoration:none;

a {text-decoration:none;}
a:hover {text-decoration:underline;}
a:before {content:'>\a0'; text-decoration:underline; display:inline-block;}
a:before,
a:hover:before {text-decoration:none;}

Working example here: http://jsfiddle.net/95C2M/

Update: Since jsfiddle does not work with IE8 anymore, just paste this simple demo-code in a local html file and open it in IE8:

<!DOCTYPE html>
<html>
<head>
    <title>demo</title>
    <style type="text/css">
        a {text-decoration:none;}
        a:hover {text-decoration:underline;}
        a:before {content:'>\a0'; text-decoration:underline; display:inline-block;}
        a:before,
        a:hover:before {text-decoration:none;}
    </style>
</head>
<body>
    <a href="#">Testlink</a> With no Underline on hover under before-content
</body>
</html>
LeJared
  • 1,986
  • 1
  • 15
  • 28
  • Had a case were **IE8 underlining** of a hyperlinked image could only be turned off by `` inside (and here was the key) `` – Bob Stein Jul 13 '14 at 21:26
  • Unfortunately that jsfiddle can't be verified in IE8 because jsfiddle doesn't work in IE8. – user2867288 Jan 20 '15 at 19:04
  • Unfortunately I could not find any online code sharing tool that still works with IE8. I've added a code snipped to the answer above which you can just paste into an html file and open it locally in IE8. – LeJared Jan 21 '15 at 16:34
  • Tested and approved on IE9, event without two different states. – saeraphin Sep 25 '15 at 10:52
  • Had a link with an icon in :before that was supposed to NOT be underlined in resting state, then be underlined on hover, but not the icon. Here is what I had to do to convince IE to get this right: a {text-decoration: none} a:before {text-decoration: underline} a:before {text-decoration: none} (yes really, first underline, then overwrite with none) a:hover {text-decration: underline} a:hover:before {text-decoration: none} – Fake Haak Jul 08 '16 at 09:10
  • This was the only solution that worked for me on IE11 without additional markup. Thanks! – triskweline Apr 04 '17 at 08:24
  • I don't get why it's working. It's so dumb, that I can't stop laughing but more important it has solved my problem. I've tried also other solutions but with no success. Thanks. – kwiat1990 Jul 17 '17 at 12:27
  • Sadly doesn't seem to work in combination with :nth-child in IE. Edit: Never mind! As long as you set the style before the nth-loop its fine! – Cammy Aug 19 '17 at 19:46
8

You can do it adding the following to the :before element:

display: inline-block;
white-space: pre-wrap;

With display: inline-block the underline disappears. But then the problem is that the space after the triangle collapses and is not shown. To fix it, you can use white-space: pre-wrap or white-space: pre.

Demo: http://jsfiddle.net/r42e5/9/

Oriol
  • 225,583
  • 46
  • 371
  • 457
1

Wrap your links in spans and add the text-decoration to the span on the a:hover like this,

a:hover span {
   text-decoration:underline;
}

I have updated your fiddle to what I think you are trying to do. http://jsfiddle.net/r42e5/4/

Udders
  • 6,340
  • 22
  • 91
  • 164
  • Good idea. That was how I did it before. The problem is that this link is produced in a cms-system and our customers are filling this in as rich-text themselves. – OptimusCrime Jan 11 '12 at 13:49
  • what language is the CMS? Could get it to spit out link and then wrap it in a span before sending it to the browser? – Udders Jan 11 '12 at 13:50
  • The company is using modx. I guess I could do that as a last way out, but I really wanted to void that. Guess it's not possible. Thanks anyways. – OptimusCrime Jan 11 '12 at 14:11
-2

try using instead:

#test p:before {
    color: #B2B2B2;
    content: "► ";
    text-decoration: none;
}

will that do?

Elen
  • 2,347
  • 3
  • 23
  • 46
-4

use this

#test  p:before {
    color: #B2B2B2;
    content: "► ";

}
Bipin Chandra Tripathi
  • 2,472
  • 3
  • 24
  • 43