CSS Pseudo-Elements

A CSS pseudo-element lets you style a specific part of an HTML element without adding another element to the HTML. Pseudo-elements can target parts such as the first letter or first line of text and can also create generated content before or after an element's content.

Pseudo-Element Syntax

A pseudo-element is normally written with two colons (::) followed by the pseudo-element name. It is attached directly to another selector without a space.

p::first-letter {
  font-size: 2em;
}

The selector p::first-letter targets the first letter of each matching paragraph rather than the entire <p> element.

Modern CSS uses the double-colon syntax to distinguish pseudo-elements from pseudo-classes, which normally use a single colon.

The ::first-letter Pseudo-Element

The ::first-letter pseudo-element targets the first letter of the first formatted line of a block container, allowing it to be styled differently from the surrounding text.

p::first-letter {
  color: #0088cc;
  font-size: 2em;
  font-weight: bold;
}
<p>Learning HTML and CSS makes it possible to create and style web pages.</p>
Browser Result

Learning HTML and CSS makes it possible to create and style web pages.

This technique can be used to create a decorative first letter without placing the first character inside a separate HTML element.

The ::first-line Pseudo-Element

The ::first-line pseudo-element targets the first formatted line of text in a block container.

p::first-line {
  font-weight: bold;
}

Unlike selecting a fixed amount of text in the HTML, the actual text included in the first line depends on factors such as the width of the element, font size, and available screen space.

Because the first formatted line can change as the page width changes, ::first-line is useful when the style should follow the visual first line rather than particular words.

The ::before Pseudo-Element

The ::before pseudo-element creates a generated pseudo-element as the first child of the selected element. It is commonly used with the CSS content property.

.note::before {
  content: "Note: ";
  font-weight: bold;
}
<p class="note">Remember to save your work.</p>
Browser Result

Note: Remember to save your work.

The text supplied by content appears before the paragraph's existing content without adding the word Note: to the HTML markup.

The ::after Pseudo-Element

The ::after pseudo-element creates a generated pseudo-element as the last child of the selected element. Like ::before, it is commonly used with the content property.

.required-label::after {
  content: " *";
  color: red;
}
<label class="required-label" for="email">Email</label>
<input type="email" id="email" name="email" required>
Browser Result

Email *

The generated asterisk appears after the label's existing content. Important information should still be represented meaningfully in the HTML and should not rely only on generated visual content.

The ::marker Pseudo-Element

The ::marker pseudo-element targets the marker of a list item, such as a bullet or number.

li::marker {
  color: #0088cc;
  font-weight: bold;
}
<ul>
  <li>HTML</li>
  <li>CSS</li>
  <li>JavaScript</li>
</ul>

This allows the list markers to be styled separately from the text contained in each <li> element.

The ::selection Pseudo-Element

The ::selection pseudo-element styles the portion of text that a user has highlighted or selected.

::selection {
  color: white;
  background-color: #0088cc;
}

When the user selects text on the page, supported properties can change the appearance of that selected text. This can help the selection visually fit the design while still remaining clearly distinguishable.

Generated Content

The ::before and ::after pseudo-elements are frequently used with the content property to add decorative or supplemental generated content.

.external::after {
  content: " ↗";
}
<a class="external" href="https://www.example-web.site/">Example Website</a>

The generated symbol is created by CSS and does not need a separate HTML element. Generated content is best suited to presentation and supplemental information rather than essential page content that users must be able to access and understand.

Pseudo-Elements vs Pseudo-Classes

Pseudo-elements and pseudo-classes extend ordinary CSS selectors in different ways. A pseudo-class selects an element according to a state or condition, while a pseudo-element targets a particular part of an element or a generated pseudo-element.

Type Example Purpose
Pseudo-class a:hover Selects a link while it is being hovered
Pseudo-element p::first-letter Targets the first letter of a paragraph
Pseudo-element .note::before Creates generated content before existing content

The difference is also visible in the usual syntax: pseudo-classes use one colon, such as :hover, while pseudo-elements use two colons, such as ::first-letter.

When to Use Pseudo-Elements

Pseudo-elements are useful when a design needs to style a particular part of an element without changing the HTML structure. They can style first letters, first lines, list markers, selected text, and generated content placed before or after an element's existing content.

p::first-letter {
  font-weight: bold;
}

li::marker {
  color: #0088cc;
}

.note::before {
  content: "Note: ";
}

Use pseudo-elements for presentation when they make the CSS simpler and the HTML more meaningful. Essential information should generally remain in the HTML rather than existing only as generated CSS content.

Summary

CSS pseudo-elements target specific parts of HTML elements or create generated pseudo-elements that can be styled with CSS. Common pseudo-elements include ::first-letter, ::first-line, ::before, ::after, ::marker, and ::selection.

Pseudo-elements normally use two colons, distinguishing them from pseudo-classes such as :hover and :focus. With pseudo-elements complete, you have now covered the main CSS selector types needed for this HTML tutorial series.