Pseudo-element Selectors

A pseudo-class acts as if we have added a class to an element that is already in the document. A pseudo-element acts as if a whole new element was inserted, then CSS applied.

Pseudo-elements match virtual elements that do not exist in the document tree.

The CSS Layout Workshop: Pseudo-element selectors

Pseudo-elements in CSS2.1 started with a single colon :, just like pseudo-classes. In Level 3 of the specification they are described using a double colon :: to distinguish them. Modern browsers support both in most cases, exceptions are:

I am using the :: syntax here, but you will see examples on the web using : and you might choose to use the single colon syntax if you need to ensure support for older versions of Internet Explorer.


The first character of the first line of text.

The first-letter pseudo-element is a good place to start to see how these selectors work.

If we want to style the first letter of a paragraph without using a pseudo-element we would need to wrap it in a span. For example.

<p class="intro"><span>H</span>ello, World!</p>
.intro span { font-size: 200%; }

The first-letter selector targets that first-letter without the need of the span. However it acts just as if a virtual span or other element were added.

<p class="intro">Hello, World!</p>
.intro::first-letter { font-size: 200%; }

All of our virtual elements act in the same way as first-letter.


The first formatted line of text.

The first-line pseudo-element selects the first formatted line of text.

<p class="intro"> ... </p>
.intro::first-line {
  font-size: 200%;
  font-weight: bold;
  color: red;

The first-line pseudo-element gives us something better than just wrapping the “first line” in a span. When we add that span we would be taking a guess as to what the first line actually was. In a fluid layout and with the user able to increase their font size, the first line could have more or fewer words on it than we imagine. Using first-line means that we will always get the first line - no matter how short or long that line is.

::before and ::after

The ::before and ::after pseudo-elements give us the ability to insert generated content before and after another element. We can add text in this way but as you’ll see if you go on to study my CSS Layout Fundamentals course, we can do so much more with these selectors.

As a simple example we can use ::before and ::after to add text before and after a paragraph.

<p class="story">This is my very short story.</p>
.story::before {
  content: "Once upon a time,";

.story::after {
  content: "The End.";

Here we use the content property with a value of the string we wish to insert into our document before or after the element the precedes our pseudo-element.

You can style the generated content with CSS, for example to make the content before and after display on their own lines and in italic we could do this:

.story::before {
  content: "Once upon a time.";
  display: block;
  font-style: italic;

.story::after {
  content: "The end.";
  display: block;
  font-style: italic;

We’ll take a good look at the different things that we can use generated content for in the CSS Layout Fundamentals course.

Next lesson: Selectors Usage Tips