CSS Portal

::before CSS Pseudo Element

If this site has been useful, we’d love your support! Consider buying us a coffee to keep things going strong!

Description

The ::before pseudo-element creates a generated box that is rendered immediately before an element’s actual content. It behaves like a child of the targeted element (but it does not exist in the DOM), so you can style it with most layout, visual and typographic properties to create decorative or informational content without changing the HTML.

How it works and important rules

  • It is created only when the element’s CSS includes a content property (often set to an empty string, e.g. content: "", for decorative purposes). Without a defined content, no pseudo-element is generated.
  • By default the pseudo-element is inline. You can change its layout with display (for example display: block or inline-block) to control width, height and box-model behavior.
  • It is not a real DOM node. JavaScript cannot select or attach event listeners directly to the pseudo-element; you can only affect it via CSS on the element (or by manipulating styles/CSS rules).
  • Screen-reader and accessibility behavior varies by platform and should not be relied on for conveying essential content; prefer real DOM text for content that must be accessible. Use pseudo-elements mainly for decoration and non-essential labels.
  • Because it’s rendered as a descendant, its position and stacking can be controlled using layout/positioning rules (e.g., make the parent position: relative and the pseudo-element position: absolute to overlay it).
  • A common pairing is using both ::after and ::before to create complex decorative effects (only one link per element as requested).

What you can do with it (typical uses)

  • Insert icons or glyphs before a heading or link without extra markup.
  • Add visual accents (e.g., underlines, corners, ribbons) using background, border, transform.
  • Create counters and numbering via the CSS counters API (e.g., for lists or headings).
  • Insert attribute values via attr() for small labels (still be cautious about accessibility).
  • Animate decorative effects (transitions, transforms, opacity) independently of the element’s main content.
  • Use CSS variables inside the pseudo-element for themeable decorations.

Styling and limitations

  • Most visual properties apply: color, background, border, padding, margin, width, height, transform, opacity, filter, etc.
  • Pseudo-elements can form their own stacking contexts; you can use z-index when they are positioned (position other than static).
  • Pointer behavior: pseudo-elements can receive pointer events if styled that way; to make a purely decorative element non-interactive, use pointer-events: none.
  • They cannot be referenced directly from JavaScript (no eventTarget, no element reference); changes must be applied by updating the parent’s styles, classes or stylesheet rules.
  • There are only a limited set of pseudo-elements that create boxes; ::before and ::after are the two commonly-used generated-content pseudo-elements used for this purpose.

Accessibility guidance

  • Don’t inject critical content (labels, essential instructions) with ::before; use real DOM content for anything users must be able to interact with or read with assistive tech.
  • If you must provide visible supplemental text via CSS, test with screen readers and mobile devices - behaviors differ across user agents.
  • For purely decorative icons or overlays, consider aria-hidden="true" on the element to prevent duplication in some assistive technologies (but prefer real content when semantics matter).
Examples

Basic text before a heading

h2::before {
  content: "Note: ";
  font-weight: 700;
  color: #c44;
  margin-right: 0.4em;
}

Decorative icon using background image and sizing

a.download::before {
  content: "";
  display: inline-block;
  width: 1em;
  height: 1em;
  margin-right: 0.5em;
  background-image: url("icons/download.svg");
  background-size: contain;
  background-repeat: no-repeat;
  vertical-align: middle;
}

Numbering list items with CSS counters

ol.toc {
  counter-reset: section;
}
ol.toc li::before {
  counter-increment: section;
  content: counter(section) ". ";
  font-weight: 600;
  margin-right: 0.35em;
}

Overlay ribbon using absolute positioning

.card {
  position: relative;
  overflow: visible;
}
.card::before {
  content: "New";
  position: absolute;
  top: 8px;
  right: -28px;
  transform: rotate(45deg);
  background: #ff5a5f;
  color: white;
  padding: 6px 24px;
  font-size: 0.75rem;
  box-shadow: 0 2px 6px rgba(0,0,0,0.1);
  display: block;
}

Animated underline effect

a.underline {
  position: relative;
  color: #0366d6;
  text-decoration: none;
}
a.underline::before {
  content: "";
  position: absolute;
  left: 0;
  right: 100%;
  bottom: -2px;
  height: 2px;
  background: currentColor;
  transition: right 220ms ease;
}
a.underline:hover::before {
  right: 0;
}

Small practical tips

  • Use content: "" when you want a generated box for visual styling only.
  • Set the parent to position: relative when you plan to absolutely position the pseudo-element.
  • Prefer CSS variables (--my-color) inside the parent and reference them in the pseudo-element for easier theme control.
  • Test interactions carefully: because pseudo-elements are not DOM nodes, keyboard focus or scripting cannot act on them directly.

These points should give you a practical, detailed sense of what ::before can do and how to use it effectively for visual and decorative enhancements while avoiding accessibility pitfalls.

Syntax

element::before { content: "text" };

Example

<ul>
<li>Adelaide</li>
<li>Melbourne</li>
<li>Sydney</li>
<li>Brisbane</li>
<li>Perth</li>
</ul>
li::before {
content: "→ ";
}
li {
list-style: none;
color: blue;
}

Browser Support

The following information will show you the current browser support for the CSS ::before pseudo element. Hover over a browser icon to see the version that first introduced support for this CSS psuedo element.

This psuedo element is supported by all modern browsers.
Desktop
Chrome
Edge
Firefox
Opera
Safari
Tablets & Mobile
Chrome Android
Firefox Android
Opera Android
Safari iOS
Samsung Internet
Android WebView
-

Last updated by CSSPortal on: 1st January 2026

If this site has been useful, we’d love your support! Consider buying us a coffee to keep things going strong!