Pseudo-elements in CSS -more than what you think
Tags: html, css, beginners, tutorial
Published: 2022-01-08 06:25:40

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.

![pseudo-class vs pseduo-element](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/lixmzlrsw7joc34kg8d2.png)

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.

```css
::selection {
  color: white;
  background: blue;
}
```
![::selection pseudo-element](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/v0pk8qqrfqpu0vl1e6x6.png)

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.

```css
p::first-letter {
  color: #ff0000;
  font-size: xx-large;
}

p::first-line {
  color: #0000ff;
  font-variant: small-caps;
}
```
which results in something as:

![::first-letter and :first-line pseudo elements](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/iid0mmmcjozf1o4qs70v.png)

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. 

```css
h1::before{
  content: 'before';
  background: #2867b2;
  color: white;
}
h1::after{
  content: 'after';
  background: #2867b2;
  color: white;
}
```
![::before and ::after pseudo elements](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/iw54s8067ldnifh1dzbv.png)

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**.

![CSS Devtool](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/6q68f895j2wwpc0e41xi.png)
 
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.

```css
  .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;
  }
```
![task-list](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/mcc057z37ofotjkfme6q.png)

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](https://stackoverflow.com/questions/7396469/why-dont-before-and-after-pseudo-elements-work-with-img-elements).

**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_](https://nicolasgallagher.com/css-typography-experiment/demo/bugs.html) 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.

![Linkedin Logo](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/3zhkp4tl2gbjuksolq10.png)
 
**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.