"Text-Decoration" and the ":After" Pseudo-Element

“text-decoration” and the “:after” pseudo-element, revisited

IE8's implementation of the :before and :after pseudo-elements is incorrect. Firefox, Chrome and Safari all implement it according to the CSS 2.1 specification.

5.12.3 The :before and :after pseudo-elements

The ':before' and ':after'
pseudo-elements can be used to insert
generated content before or after an
element's content. They are explained
in the section on generated text.

...

Cascading Style Sheets Level 2 Revision 1 (CSS 2.1) Specification

The specification indicates that the content should be inserted before or after the element's content, not the element (i.e. <element>content:before content content:after</element>). Thus in Firefox and Chrome the text-decoration you're encountering is not on the inserted content but rather on the parent anchor element that contains the inserted content.

I think your options are going to be using the background-image/padding technique suggested in your previous question or possibly wrapping your anchor elements in span elements and applying the pseudo-elements to the span elements instead.

text-decoration and the :after pseudo-element

I'm doing it in a different way, using attribute selectors, a background image and a padding (as xandy also suggested):

a[href$=".pdf"] {
padding-right: 21px; /* space for the icon */
background: url(graphics/pdf.png) no-repeat right bottom;
}

This works in IE7 too.

Here's a complete example

In IE7 the PDF icon won't be visible as it does not understand data URIs:

<!DOCTYPE html>

<html>
<head>
<meta charset="UTF-8">
<title>PDF</title>
<style type="text/css">
a:link,
a:visited {
color: #317408;
background: #eee;
}
a[href$=".pdf"] {
padding-right: 21px;
background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAAK/INwWK6QAAABl0RVh0U29mdHdhcmUAQWRvYmUgSW1hZ2VSZWFkeXHJZTwAAAHhSURBVDjLjZPLSxtRFIfVZRdWi0oFBf+BrhRx5dKVYKG4tLhRqlgXPmIVJQiC60JCCZYqFHQh7rrQlUK7aVUUfCBRG5RkJpNkkswrM5NEf73n6gxpHujAB/fOvefjnHM5VQCqCPa1MNoZnU/Qxqhx4woE7ZZlpXO53F0+n0c52Dl8Pt/nQkmhoJOCdUWBsvQJ2u4ODMOAwvapVAqSJHGJKIrw+/2uxAmuJgFdMDUVincSxvEBTNOEpmlIp9OIxWJckMlkoOs6AoHAg6RYYNs2kp4RqOvfuIACVFVFPB4vKYn3pFjAykDSOwVta52vqW6nlEQiwTMRBKGygIh9GEDCMwZH6EgoE+qHLMuVBdbfKwjv3yE6Ogjz/PQ/CZVDPSFRRYE4/RHy1y8wry8RGWGSqyC/nM1meX9IQpQV2JKIUH8vrEgYmeAFwuPDCHa9QehtD26HBhCZnYC8ucGzKSsIL8wgsjiH1PYPxL+vQvm5B/3sBMLyIm7GhhCe90BaWykV/Gp+VR9oqPVe9vfBTsruM1HtBKVPmFIUNusBrV3B4ev6bsbyXlPdkbr/u+StHUkxruBPY+0KY8f38oWX/byvNAdluHNLeOxDB+uyQQfPCWZ3NT69BYJWkjxjnB1o9Fv/ASQ5s+ABz8i2AAAAAElFTkSuQmCC);
background-repeat: no-repeat;
background-position: right bottom;
}
a:hover {
color: #eee;
outline: none;
background-color: #317408;
text-decoration: none;
}
</style>
</head>
<body>

<p>
<a href="document.pdf">Here's the PDF</a>
</p>

</body>
</html>

“text-decoration” and the “:after” pseudo-element, in Firefox 8

I came with up with this http://jsfiddle.net/wGb68/4/

a[href^='http://stackoverflow.com/'] {
padding-right: 15px;
display: inline-block; /* not needed, but fixes Chrome and Opera */
}

a[href^='http://stackoverflow.com/']:after {
font-size: x-small;
padding-left: 1px;
content: "SO";
color: #333;

position: absolute;
}

Poorly the clearing of the text-decoration only works in Firefox and Opera with this code. I could not bring it to work in any other browser. :/

The display: inline-block is not needed in Firefox, but without it in Opera and Chrome the "SO" don't follows a linebreak, and even overlaps the container.

Remove text-decoration underline, for a:after in css

you can use one another method also for your question :- demo

I have tried with minimized code :-

HTML

<div class="nav_container">
<a href="demolink">menu1</a>
<a href="demolink">menu2</a>
<a href="demolink">menu3</a>
</div>

CSS

.nav_container a {
color:red;
display:inline-block;
}
.nav_container a + a{
color:red;
border-left:1px solid red;
padding-left:7px;
line-height:12px;
}

Selecting and manipulating CSS pseudo-elements such as ::before and ::after using javascript (or jQuery)

You could also pass the content to the pseudo element with a data attribute and then use jQuery to manipulate that:

In HTML:

<span>foo</span>

In jQuery:

$('span').hover(function(){
$(this).attr('data-content','bar');
});

In CSS:

span:after {
content: attr(data-content) ' any other text you may want';
}

If you want to prevent the 'other text' from showing up, you could combine this with seucolega's solution like this:

In HTML:

<span>foo</span>

In jQuery:

$('span').hover(function(){
$(this).addClass('change').attr('data-content','bar');
});

In CSS:

span.change:after {
content: attr(data-content) ' any other text you may want';
}

Add a space ( ) after an element using :after

Explanation

It's worth noting that your code does insert a space

h2::after {
content: " ";
}

However, it's immediately removed.

From Anonymous inline boxes,

White space content that would subsequently be collapsed away
according to the 'white-space' property does not generate any
anonymous inline boxes.

And from The 'white-space' processing model,

If a space (U+0020) at the end of a line has 'white-space' set to
'normal', 'nowrap', or 'pre-line', it is also removed.

Solution

So if you don't want the space to be removed, set white-space to pre or pre-wrap.

h2 {

text-decoration: underline;

}

h2.space::after {

content: " ";

white-space: pre;

}
<h2>I don't have space:</h2>

<h2 class="space">I have space:</h2>

What is :hover::after?

::after and :hover are pseudo-elements. If you have a:hover, the following styles will apply on the element when hovering over it. But, when you have a:hover::after, the following styles will apply on the pseudo-element ::after, when hovering over the element. It this case, the ::after pseudo-element represents the expanding line. And by the way to make it clear what is ::after, in CSS using the content attribute, you can also define the HTML content to be shown in the ::after pseudo-element, but in this case, you don't need to put any content there, it's just an empty shape.

Pseudo Class 'nth-child()' not working with ':hover

That's because the a isn't the 2nd child - it is an only child of it's parent li. What you are looking for is the a child of the 2nd li element. You can get that like this:

li:nth-child(2) a{ color: green; }

Then for the hover, either of these work with the code in your question. It depends on what you want to target with the hover:

// When the <a> in the second li is hovered, change it's colour
li:nth-child(2) a:hover{ color: green; }

/* OR */

/* When the second li is hovered, change the colour of the <a> it contains */
li:nth-child(2):hover a{ color: green; }

Working Example (using different colours to show it working):

ul {
background-color: white;
text-decoration: none;
padding: 0;
margin: 0 auto;
}
ul li {
margin: 0 2em;
display: inline-block;
padding: 0;
list-style: none;
}
ul li a {
text-decoration: none;
color: black;
}

/* change colour of 2nd link */
li:nth-child(2) a{
color: blue;
}

/* change colour of 2nd link on hover */
li:nth-child(2):hover a{
color: green;
}

/* change colour of 3rd link on hover */
li:nth-child(3) a:hover{
color: red;
}
<ul>
<li><a href="#">Easy</a></li>
<li><a href="#">Medium</a></li>
<li><a href="#">Hard</a></li>
<li><a href="#">Insane</a></li>
</ul>

How can I write a ':hover' condition for 'a:before' and 'a:after'?

This depends on what you're actually trying to do.

If you simply wish to apply styles to a :before pseudo-element when the a element matches a pseudo-class, you need to write a:hover:before or a:visited:before instead. Notice the pseudo-element comes after the pseudo-class (and in fact, at the very end of the entire selector). Notice also that they are two different things; calling them both "pseudo-selectors" is going to confuse you once you run into syntax problems such as this one.

If you're writing CSS3, you can denote a pseudo-element with double colons to make this distinction clearer. Hence, a:hover::before and a:visited::before. But if you're developing for legacy browsers such as IE8 and older, then you can get away with using single colons just fine.

This specific order of pseudo-classes and pseudo-elements is stated in the spec:

One pseudo-element may be appended to the last sequence of simple selectors in a selector.

A sequence of simple selectors is a chain of simple selectors that are not separated by a combinator. It always begins with a type selector or a universal selector. No other type selector or universal selector is allowed in the sequence.

A simple selector is either a type selector, universal selector, attribute selector, class selector, ID selector, or pseudo-class.

A pseudo-class is a simple selector. A pseudo-element, however, is not, even though it resembles a simple selector.

However, for user-action pseudo-classes such as :hover1, if you need this effect to apply only when the user interacts with the pseudo-element itself but not the a element, then this is not possible other than through some obscure layout-dependent workaround. As implied by the text, standard CSS pseudo-elements cannot currently have pseudo-classes. In that case, you will need to apply :hover to an actual child element instead of a pseudo-element.


1 Of course, this does not apply to link pseudo-classes such as :visited as in the question, since pseudo-elements aren't links.

Inline elements shifting when made bold on hover

Pre-set the width by using an invisible pseudo-element which has the same content and styling as the parent hover style. Use a data attribute, like title, as the source for content.

li {
display: inline-block;
font-size: 0;
}

li a {
display:inline-block;
text-align:center;
font: normal 16px Arial;
text-transform: uppercase;
}

a:hover {
font-weight:bold;
}

/* SOLUTION */
/* The pseudo element has the same content and hover style, so it pre-sets the width of the element and visibility: hidden hides the pseudo element from actual view. */
a::before {
display: block;
content: attr(title);
font-weight: bold;
height: 0;
overflow: hidden;
visibility: hidden;
}
<ul>
<li><a href="#" title="height">height</a></li>
<li><a href="#" title="icon">icon</a></li>
<li><a href="#" title="left">left</a></li>
<li><a href="#" title="letter-spacing">letter-spacing</a></li>
<li><a href="#" title="line-height">line-height</a></li>
</ul>


Related Topics



Leave a reply



Submit