A pseudo-element (double colon ::) styles a specific part of an element, or generates content that isn't in the HTML — without adding extra markup.
::before and ::after — generated content
{
: ;
}
{
: ;
}
A pseudo-element (double colon ::) styles a specific part of an element, or generates content that isn't in the HTML — without adding extra markup.
{
: ;
}
{
: ;
}
The content property is mandatory — without it, the pseudo-element doesn't render. The generated content is a child at the very start (::before) or end (::after) of the element.
.tooltip::after {
content: ""; /* empty but present → creates a box */
position: absolute;
border: 8px solid transparent;
border-top-color: black; /* a CSS triangle (tooltip arrow) */
}
This is the classic use: drawing arrows, badges, overlays, decorative lines — keeping the HTML clean of purely-visual elements.
p::first-line { font-weight: bold; } /* the first rendered line */
p::first-letter { font-size: 3em; } /* drop cap */
::selection { background: yellow; } /* highlighted/selected text */
input::placeholder { color: gray; } /* placeholder text */
.x:hover { } /* pseudo-CLASS (state) — one colon */
.x::before { } /* pseudo-ELEMENT (a part) — two colons */
CSS3 introduced :: to distinguish pseudo-elements from pseudo-classes (browsers still accept single colon on the old ones for compatibility, but use ::).
Generated content is read by some screen readers — don't put essential information only in ::before/::after (use it for decoration), and decorative icons are best left out of the accessibility tree.
Pseudo-elements let you add icons, decorative shapes (arrows, dividers), drop caps, and counters purely in CSS — no extra <div>s or <span>s.
They keep markup semantic while enabling rich visual detail, and they're a staple of clean, maintainable styling.