Introduction
CSS pseudo-elements let you style specific parts of an element or inject content without changing HTML. ::before and ::after are most known, but there are several more.
Essential for decorative elements, custom list markers, text selections, and creative techniques — all without touching the DOM.
This guide covers the full range with practical production patterns.
Key Concepts
::before and ::after
.badge::before {
content: "";
display: inline-block;
width: 8px; height: 8px;
border-radius: 50%;
background: var(--status-color);
margin-inline-end: 0.5rem;
}
.external-link::after { content: " ↗"; font-size: 0.75em; }
::marker
li::marker {
color: var(--color-primary);
font-weight: 700;
}
::selection and ::placeholder
::selection { background: oklch(0.7 0.15 250 / 0.3); }
input::placeholder { color: var(--text-muted); font-style: italic; }
Practical Examples
1. Decorative Underline
.section-title::after {
content: "";
display: block;
width: 3rem; height: 3px;
background: var(--color-primary);
margin-top: 0.5rem;
}
2. Image Overlay
.card-image::after {
content: "";
position: absolute;
inset: 0;
background: linear-gradient(to top, rgba(0,0,0,0.7), transparent);
pointer-events: none;
}
3. Tooltip Arrow
.tooltip::before {
content: "";
position: absolute;
top: 100%; left: 50%;
translate: -50% 0;
border: 6px solid transparent;
border-top-color: var(--surface);
}
Best Practices
- Always set content (even to '') — won't render without it.
- Use for decorative content only — not accessible text.
- Pseudo-elements are children, not siblings.
- Use ::marker for list styling instead of ::before hacks.
- Add pointer-events: none to overlays.
- Can't add to void/replaced elements (img, input, br).
Common Pitfalls
- Adding to <img>, <input>, <br> — void elements don't support them.
- Forgetting content: '' — element won't render.
- Using for accessible content — screen readers are inconsistent.
- Not setting display: block/inline-block for width/height.
Browser Support
::before/::after: universal. ::marker: Chrome 86+, Safari 11.1+, Firefox 68+. ::selection/::placeholder: universal.
Related Guides
- CSS Animation & Keyframes — animate pseudo-elements
- CSS Custom Properties — variables in pseudo-element styles
- CSS Filter Effects — filters on pseudo-element overlays