CSS ::before Pseudo-Element

Learn to generate virtual elements at the start of any selected element for decorative content without modifying HTML

What is the CSS ::before Pseudo-Element?

The CSS ::before pseudo-element represents a virtual element that is the first child of the selected element. This powerful CSS feature allows developers to insert decorative or functional content without modifying the HTML structure, making it an essential tool for building modern, maintainable websites.

When working with contemporary web development frameworks like Next.js and React, understanding pseudo-elements like ::before becomes crucial for creating polished user interfaces without cluttering component markup. Our web development services leverage these CSS techniques to build clean, efficient stylesheets for client projects.

Syntax and Basic Usage

The ::before pseudo-element follows a straightforward syntax pattern. Introduced in CSS Selectors Level 3, the double-colon notation (::before) distinguishes pseudo-elements from pseudo-classes (which use a single colon).

The fundamental syntax requires targeting an element and applying the ::before selector, followed by the content property which determines what the pseudo-element displays. Without the content property, the ::before pseudo-element will not render.

Basic ::before Syntax
1/* Basic syntax for ::before */2.element::before {3 content: "→ ";4 display: inline-block;5 margin-right: 0.5em;6}7 8/* Single-colon syntax (legacy, still supported) */9.element:before {10 content: "→ ";11}

Content Property Values

The content property is the cornerstone of working with ::before pseudo-elements. It determines exactly what the pseudo-element will render, and understanding its various accepted values is essential for effective implementation.

String values, enclosed in quotes, represent literal text that appears within the pseudo-element. These can be empty strings for spacing purposes, or contain Unicode characters for special symbols and icons. String content is the most common use case and works across all browsers without limitations.

URL values enable you to reference images or other media directly within the content property, making it possible to create image-based decorations without additional HTML markup. This approach is particularly useful for adding icons, logos, or decorative graphics to elements throughout your website.

The attr() function represents perhaps the most powerful content value option, as it dynamically extracts attribute values from the parent element. When combined with data attributes, this enables sophisticated content generation that responds to HTML changes without JavaScript intervention. For instance, you can display tooltips, labels, or status indicators that automatically update when underlying attributes change.

Content Property Examples
1/* String content */2.card::before {3 content: "NEW";4 background: #007bff;5 color: white;6 padding: 0.25em 0.5em;7 font-size: 0.75em;8 border-radius: 3px;9 margin-right: 0.5em;10}11 12/* Image content */13.icon-link::before {14 content: url("/images/external-link.svg");15 width: 1em;16 height: 1em;17 margin-right: 0.25em;18}19 20/* Attribute-based content */21.element::before {22 content: attr(data-label);23 display: block;24 margin-bottom: 0.5em;25 font-weight: bold;26}

Browser Compatibility

The ::before pseudo-element enjoys universal browser support across all modern browsers, having achieved Baseline status in July 2015. Browser support spans Chrome, Firefox, Safari, Edge, and virtually all other contemporary browsers.

For development teams working with Next.js or other modern frameworks, this compatibility means ::before can be used freely in global styles, component-level CSS, or utility classes without conditional logic.

Common Use Cases

Practical applications of the ::before pseudo-element

Adding Icons

Inject visual icons into links, buttons, and interactive elements without additional HTML markup

Quotation Marks

Add decorative quotation marks to blockquotes and testimonials for enhanced typography

Status Indicators

Create dynamic badges and labels using attr() with data attributes

Decorative Lines

Add visual separators and decorative elements to enhance content hierarchy

Interactive Feedback

Show state changes through before/after content swaps on user interaction

Custom List Markers

Replace default bullets with custom symbols or images via content property

Interaction with JavaScript

JavaScript can interact with ::before pseudo-elements through several mechanisms:

Class Manipulation

The most common approach involves toggling classes that target the pseudo-element through CSS rules. JavaScript adds, removes, or toggles classes while CSS handles presentation.

Attribute Updates

Since ::before can use the attr() function, JavaScript can update HTML attributes to automatically reflect changes in pseudo-element content.

CSS Custom Properties

Modern CSS variables provide another avenue--JavaScript updates custom properties on elements to modify pseudo-element styling.

When building dynamic web applications, combining JavaScript services with advanced CSS pseudo-elements creates responsive, interactive user interfaces without sacrificing performance.

JavaScript Interaction Example
1// Toggle class to update ::before content2element.addEventListener('click', () => {3 element.classList.toggle('expanded');4});5 6// Update data attribute for attr() content7function updateStatus(newStatus) {8 element.setAttribute('data-status', newStatus);9}10 11// CSS uses class/attribute for ::before behavior12.dropdown::before {13 content: "▶";14 transition: transform 0.3s ease;15}16 17.dropdown.expanded::before {18 content: "▼";19}

::before vs ::after

Both pseudo-elements generate virtual children of the selected element, but differ in position:

Aspect::before::after
PositionBefore element's contentAfter element's content
Default stack orderBelow ::afterAbove ::before
Common useIcons, labels, headersClosing marks, footers

When both are present, ::after renders above ::before by default. Use z-index to modify this stacking order if needed. For symmetrical designs like quotation marks, combining both creates balanced presentation without additional markup.

See also our guide on the ::after pseudo-element for complementary techniques.

Best Practices for Modern Web Development

Should I use component-level or global styles?

Define ::before pseudo-elements within component-specific stylesheets when possible. This ensures encapsulation and makes components more portable.

What properties affect performance?

Avoid excessive use of filter, transform, or box-shadow on pseudo-elements in performance-critical paths. Transform and opacity animations perform best.

How do I debug ::before in DevTools?

In Chrome DevTools, pseudo-elements appear in the Elements panel beneath their parent element with a specialized marker. Click to inspect properties.

When should I avoid ::before?

Avoid ::before for essential content, dynamic content requiring frequent updates via JavaScript, or when the visual result must be accessible to screen readers.

Build Modern Websites with Digital Thrive

Our expert developers leverage modern CSS techniques including pseudo-elements to create performant, accessible websites.

Sources

  1. MDN Web Docs - ::before - Official CSS documentation covering syntax, browser support, and accessibility guidance
  2. DEV Community - ::before/::after Pseudo Elements Guide - Practical examples and implementation patterns