Advanced20 min read

Pseudo-Elements

Learn to style specific parts of elements using CSS pseudo-elements like ::before, ::after, ::first-line, and ::first-letter without adding extra HTML.

What Are Pseudo-Elements?

A pseudo-element lets you style a specific part of an element, or insert generated content, without adding extra HTML markup. They use the double-colon prefix :: to distinguish them from pseudo-classes (single colon :).

The most commonly used pseudo-elements are:

  • ::before — Inserts generated content before the element's actual content.
  • ::after — Inserts generated content after the element's actual content.
  • ::first-line — Styles the first line of a block-level element (the amount of text depends on the element's width).
  • ::first-letter — Styles the first letter of a block-level element (great for drop caps).
  • ::placeholder — Styles the placeholder text of form inputs.
  • ::selection — Styles text that the user has highlighted.

Important: ::before and ::after require the content property to work, even if it is an empty string content: "".

Decorative Elements with ::before and ::after

html
<style>
  .fancy-heading {
    font-size: 24px;
    text-align: center;
    color: #333;
  }

  /* Add a decorative star before the heading */
  .fancy-heading::before {
    content: "\2605 ";
    color: gold;
  }

  /* Add a decorative star after the heading */
  .fancy-heading::after {
    content: " \2605";
    color: gold;
  }

  /* Drop cap effect */
  .article-text::first-letter {
    font-size: 2em;
    font-weight: bold;
    color: darkblue;
    float: left;
    margin-right: 4px;
  }

  .article-text::first-line {
    font-variant: small-caps;
  }
</style>

<h1 class="fancy-heading">Welcome</h1>
<p class="article-text">
  Once upon a time, there was a web developer who
  discovered the power of pseudo-elements. They could
  add decorations without extra HTML markup.
</p>

The Content Property

The content property is what makes ::before and ::after work. Without it, the pseudo-element will not render.

Values for the content property

  • Stringcontent: "Hello" inserts the text "Hello".
  • Empty stringcontent: "" renders an empty box you can style (useful for decorative shapes).
  • attr()content: attr(data-label) pulls the value of an attribute from the element.
  • Unicode escapecontent: "\2022" inserts a bullet character.
  • URLcontent: url(icon.png) inserts an image (less common).

Common use cases

  • Adding icons or decorations without extra markup.
  • Creating custom list markers or quote marks.
  • Building CSS-only tooltips.
  • Adding required-field indicators to form labels (content: " *" with color red).

Note: Content generated by pseudo-elements is not part of the DOM and is not accessible to screen readers in all browsers. Do not use it for essential information.

What happens if you use ::before without setting the content property?

Ready to practice?

Create your free account to access the interactive code editor, run challenges, and track your progress.