The versatility of CSS is used to control the appearance and the format of the HTML document tree. But one powerful feature that is often overlooked due to lack of understanding is pseudo-elements. As the name suggests they are not a part of the real DOM, rather a CSS abstraction that provides additional but inaccessible information in the webpage. This allows us to show something on the document which might not be present in the HTML content. Keeping in mind, we shouldn’t use it for actual content insertion, as pseudo-elements can’t be selected or manipulated on the page. They are more of a decorative content of the webpage.
We will discuss a few use cases of pseudo-elements and how you can implement them wisely in your next project. One thing to remember is the syntax, often they are written with single colon (:) as per the original specification but after level three specification (CSS3) to make it distinguishable from pseudo-classes it was changed to double-colon (::). And as we already know the goal of the web is to always keep it backward compatible, so both of them work to the date. But we should stick to double-colon (::).
You must have seen websites that are based on a color theme where selecting the text, changes the background color or the text color. This can be achieved by using ::selection
pseudo-element. The ::selection
pseudo-element matches the portion of an element that is selected by a user. Then properties like ::selection:
color, background, cursor, and outline can be added on to them.
::selection {
color: white;
background: blue;
}
Other pseudo-elements like ::first-line
and ::first-letter
does exactly what you think. They are used to style the first line and the first letter of a text.
p::first-letter {
color: #ff0000;
font-size: xx-large;
}
p::first-line {
color: #0000ff;
font-variant: small-caps;
}
which results in something as:
Perhaps the most powerful among all are ::before
and ::after
pseudo-elements. Let’s see how they work:
In this example we have a heading (<h1>
) tag in HTML body placed in the middle of the page, we can select the pseudo-element of this heading and add a ::before
and ::after
to it, with some styling. But it doesn’t work without an empty content string, which technically allows to target the particular element.
h1::before{
content: 'before';
background: #2867b2;
color: white;
}
h1::after{
content: 'after';
background: #2867b2;
color: white;
}
In the browser inspector it shows up and we can style it as if it is an empty div or span in our HTML. This can be very helpful to design content without adding unnecessary markup in HTML. A basic misconception that revolves around ::before
and ::after
is that, they appear before the HTML tag. That’s clearly not the case, pseudo-elements only occur before the targeted content of the element.
Imagine we have ordered (<ol>
) and unordered (<ul>
) lists in the HTML, and we want to add default emoji before each of them. A clean way to implement this without duplicating in the markup, will be to use ::before
with the emoji as the content of the string.
.task-list {
list-style: none;
}
.task-list li {
font-size: 2em;
margin-bottom: 10px;
}
.task-list li::before {
content: "✅";
margin-right: 15px;
font-size: 20px;
}
Other use cases can be – different types of CSS Polygon stylings, Speech bubbles, creating CSS ribbons, gradient overlays, and borders, the list goes on.
Concerns
One thing to be cautioned about is not to use pseudo-elements on image (<img>
) tags, as they just don’t work. The reason can be complicated, as images don’t have a spare ‘content’ model, they are called replaced-element thus image itself is the content. Keeping this in mind will save your precious time trying to debug why it’s not working. You can give it a read here.
Browser Support
When it comes to browser support, ::first-line
and ::first-letter
pseudo-elements were introduced in CSS1 so there is the basic support for them (except IE6 and IE7 have particularly buggy implementations; even modern browsers are not entirely consistent in the way that they handle the :first-line
and :first-letter
pseudo-elements). Here are some example bugs while using pseudo elements in different browsers.
On the other hand ::before
and ::after
are mostly classified as progressive enhancement, which can be classified as a modern approach to design and development. The :before
and :after
pseudo-elements were introduced in the CSS2.1 specification and are fully implemented in Firefox 3.5+, IE 8+, Safari 3+, Google Chrome, and Opera browsers.
Future of Pseudo-Elements
Just like any other development tool, pseudo-elements in CSS are only here to evolve with time. As new implementation will take place whereas, existing ones will be of no use as CSS3 continues to improve.
Top comments (2)
Pay attention when copying thing from the Net. The article you copied (nicolasgallagher.com/an-introducti...) is 10 years old so many things you took from there are no more relevant
While studying about browser support for pseudo-elements, I came across the blog. I'm not particularly aware of the things that you're finding irrelevant. As per my knowledge, CSS1 introduced ::first-line and ::first-letter also, the fact that ::before-::after are progressive enhancement, do not justify to me either. Kindly elaborate.