The Complete CSS Pseudo-elements Cheatsheet: Mastering :before and :after

Introduction: What Are CSS Pseudo-elements?

Pseudo-elements are CSS selectors that allow you to style specific parts of an element without adding extra markup to your HTML. The most powerful and widely used pseudo-elements are ::before and ::after, which let you insert and style content before or after an element’s content.

Core Concepts of CSS Pseudo-elements

Basic Syntax

selector::before {
    content: "text content";  /* Required property */
    /* Other CSS properties */
}

selector::after {
    content: "";  /* Required even if empty */
    /* Other CSS properties */
}

Key Features

  • Double vs. Single Colon: Modern syntax uses double colons (::before), but single colons (:before) work for backward compatibility
  • Content Property: The content property is mandatory, even if empty ("")
  • Display Value: Pseudo-elements are inline by default but can be changed
  • DOM Position: Not part of the DOM, cannot be selected with JavaScript directly
  • Inheritance: Inherit properties from their parent elements
  • Accessibility: Content added via pseudo-elements is not accessible to screen readers

How to Use Pseudo-elements: Step-by-Step

  1. Select the target element using a CSS selector
  2. Add the pseudo-element (::before or ::after)
  3. Define the content property (required)
  4. Position the element (using position, display, etc.)
  5. Style the pseudo-element with CSS properties
  6. Test across browsers for compatibility

Key Techniques by Category

Text and Typography

/* Add quotation marks */
blockquote p::before {
    content: """;
    font-size: 2em;
    color: #888;
}
blockquote p::after {
    content: """;
    font-size: 2em;
    color: #888;
}

/* Add labels */
.required::after {
    content: "*";
    color: red;
    margin-left: 4px;
}

Icons and Decorative Elements

/* Add icons using Unicode */
.external-link::after {
    content: " \2197";  /* ↗ character */
    font-size: 0.8em;
}

/* Add icons using images */
.download::before {
    content: "";
    display: inline-block;
    width: 16px;
    height: 16px;
    background-image: url('download-icon.svg');
    background-size: contain;
    margin-right: 5px;
}

Layout and Structural Elements

/* Clearfix for floated elements */
.clearfix::after {
    content: "";
    display: table;
    clear: both;
}

/* Create triangles */
.tooltip::after {
    content: "";
    position: absolute;
    bottom: -10px;
    left: 50%;
    margin-left: -10px;
    border-width: 10px 10px 0;
    border-style: solid;
    border-color: #555 transparent transparent;
}

Interactive Elements

/* Hover effects */
.button::before {
    content: "";
    position: absolute;
    top: 0;
    left: 0;
    width: 0;
    height: 100%;
    background-color: rgba(255,255,255,0.2);
    transition: width 0.3s;
}
.button:hover::before {
    width: 100%;
}

Comparison: ::before vs. ::after

Feature::before::after
PositionInserted before the content of the elementInserted after the content of the element
DOM orderFirst child of the elementLast child of the element
Stacking order (default)Below the element’s contentAbove the element’s content
Use casesPrefixes, decorative elements before contentSuffixes, appended information, clearfix
Z-index behaviorCan be controlled with z-index if positionedCan be controlled with z-index if positioned

Common Challenges and Solutions

Challenge: Content Not Appearing

Solution:

  • Ensure the content property is defined (even if empty)
  • Check that the element is not display: none
  • Verify the element has dimensions (width/height or positioned content)

Challenge: Positioning Issues

Solution:

  • Use position: absolute and position relative to the parent element
  • Add position: relative to the parent element
  • Set appropriate top, right, bottom, and left values

Challenge: Responsiveness

Solution:

  • Use relative units (em, rem, %) instead of pixels
  • Consider using media queries to adjust pseudo-element behavior
  • Test on various screen sizes

Challenge: Browser Compatibility

Solution:

  • Use vendor prefixes when necessary
  • Test across browsers
  • Provide fallbacks for older browsers

Best Practices and Tips

  • Keep content presentational: Use pseudo-elements for decorative purposes, not essential content
  • Performance: Minimize the use of complex pseudo-elements on frequently animated elements
  • Debugging: Use background colors temporarily to visualize pseudo-elements
  • Organization: Group pseudo-element styles with their parent elements in your CSS
  • Specificity: Be mindful of selector specificity to avoid unexpected overrides
  • Combinatorial power: Combine with other selectors (like :hover) for complex interactions
  • Content values: Use quotes for strings, URLs for images, and attr() for dynamic content

Advanced Techniques

Using attr() to Pull Content from HTML

a::after {
    content: " (" attr(href) ")";
    font-size: 0.8em;
    color: #666;
}

/* Shows the title attribute on hover */
[title]::after {
    content: attr(title);
    position: absolute;
    display: none;
    padding: 5px;
    background: #333;
    color: white;
}
[title]:hover::after {
    display: block;
}

Using Multiple Pseudo-elements with Generated Content

/* Using multiple pseudo-elements for complex designs */
.fancy-box {
    position: relative;
}
.fancy-box::before {
    content: "";
    position: absolute;
    top: -5px;
    left: -5px;
    right: -5px;
    bottom: -5px;
    background: linear-gradient(45deg, #f00, #00f);
    z-index: -1;
}
.fancy-box::after {
    content: "";
    position: absolute;
    top: -2px;
    left: -2px;
    right: -2px;
    bottom: -2px;
    background: white;
    z-index: -1;
}

CSS Counters with Pseudo-elements

/* Automatic numbering with CSS counters */
body {
    counter-reset: section;
}
h2::before {
    counter-increment: section;
    content: "Section " counter(section) ": ";
}

Resources for Further Learning

Browser Support

CSS pseudo-elements have excellent browser support across all modern browsers. Single-colon syntax (:before and :after) provides backward compatibility with older browsers that don’t support the double-colon syntax.

Scroll to Top