CSS ::before vs ::after - When to Use Each Pseudo-element

Choose between CSS ::before and ::after by understanding insertion order, accessibility tree behavior, and common patterns: icons, badges, decorative lines, and clearfix.

Pseudo-elements

Detailed Explanation

The Difference Is Insertion Order

::before inserts a generated child as the first child of the element. ::after inserts one as the last child. Visually, both render in normal flow, so a default ::before appears to the left of (or above) the element's content, and ::after appears to the right (or below).

.tag::before { content: "#"; color: #888; }
.tag::after  { content: " ↗"; color: #36c; }

For <span class="tag">design</span> you get: #design ↗.

Pick ::before When …

  • The decoration should appear first in reading order (icons, prefixes, bullets).
  • You want to push existing content rightward without affecting trailing punctuation.
  • Building decorative bars or shapes positioned at the top of an element.
.required-label::before {
  content: "* ";
  color: red;
}

Pick ::after When …

  • The decoration should appear last (trailing icons, badges, "more" indicators).
  • Implementing classic clearfix on float layouts.
  • Adding a divider beneath a heading.
.external-link::after {
  content: " ↗";
  font-size: 0.8em;
}

Both Together

For symmetric decorations like quotation marks, use both:

.pull-quote::before { content: "“"; }
.pull-quote::after  { content: "”"; }

Accessibility

Generated content from ::before and ::after is included in the accessibility tree by most modern screen readers, but support is uneven. As a rule:

  • Decorative-only icons → fine. Reader announcements may be weird but not harmful.
  • Critical text (e.g., "Required") → use real DOM, not generated content.
  • Use speak: never; (proposed) or set content: "" and use a background-image for purely decorative glyphs.

Specificity

::before and ::after each add (0, 0, 1) — same as a single type selector. They don't replace the original element's specificity; they add to the compound.

Don't Forget the content Property

Without content, neither pseudo-element renders. content: "" (empty string) is the conventional way to make a purely decorative box.

Use Case

Reach for ::before for prefix icons, leading bullets, required-field markers, and decorative top borders. Reach for ::after for trailing icons (external link arrows), "new" badges, clearfix, and underline-style heading decorations. Together they enable CSS-only quotation marks, parentheses, and balanced ornaments.

Try It — CSS Selector Reference

Open full tool