CSS Pseudo-elements
Pseudo-classes style an element when a state is true (:hover, :focus). Pseudo-elements go further: they let you style a piece of an element, or invent a tiny box before or after its real content — with a double colon (::) and no extra HTML tags.
What are CSS pseudo-elements?
A pseudo-element is a keyword starting with :: that attaches to a selector. It targets something that is not a full element in your markup: the first letter, the first line, or a generated box before/after the content. ::before and ::after usually need a content value to show anything.
Everyday pseudo-elements at a glance
Learn these four first. Older single-colon forms (:before) still work in many browsers, but write the modern double-colon style.
📊 Everyday CSS pseudo-elements
| Pseudo-element | What it styles | Example |
|---|---|---|
::before |
A box inserted before the element’s content | p::before |
::after |
A box inserted after the element’s content | a::after |
::first-letter |
The first letter of a block of text | p::first-letter |
::first-line |
The first line of a block of text | p::first-line |
Before — ::before and content
::before creates a virtual box before the element’s real content. You almost always set content — a string, or "" for an empty decorative box.
Before — opening quote mark
css.quote::before {
content: "“";
color: #0f766e;
font-size: 1.5rem;
margin-right: 0.25rem;
}
Remember content
Without content, many ::before / ::after rules show nothing. For a blank decorative box (icons via background), use content: "".
After — ::after
::after is the same idea after the content — useful for units, badges, or a small suffix.
After — external-link hint
cssa.external::after {
content: " ↗";
font-size: 0.85em;
}
Do not hide required meaning
Screen readers and some tools treat generated content inconsistently. Never put the only copy of important instructions inside ::before or ::after. Prefer real text in HTML for anything users must understand.
First letter — ::first-letter
::first-letter styles the first letter of a block container’s text — classic for a drop-cap look on an opening paragraph.
First letter — larger opening character
css.lead::first-letter {
font-size: 2.5rem;
font-weight: 700;
color: #0f766e;
float: left;
line-height: 1;
margin-right: 0.15em;
}
First line — ::first-line
::first-line styles only the first line as it wraps in the browser — not “the first sentence,” but the first visual line.
First line — slightly stronger opening line
css.lead::first-line {
font-weight: 600;
color: #334155;
}
Clearing decorative content
When you need a box with no text (for a colored bar or icon background), empty string content is enough.
Empty before — decorative bar
css.card::before {
content: "";
display: block;
height: 4px;
background: #0f766e;
margin-bottom: 0.75rem;
}
Practical habits
- Double colon for pseudo-elements (
::before); single colon for pseudo-classes (:hover) - Always set
contenton::before/::afterwhen you want something visible - Keep required reading in real HTML text, not only in generated content
::first-letterand::first-lineapply to block containers with text- Prefer modern
::spelling even if old:beforestill works
Try it yourself
- Make a short page with a paragraph classed
.quote, a paragraph classed.lead, ana.externallink, and a.carddiv with some text. - Add
.quote::before { content: "“"; color: #0f766e; }and confirm the quote mark appears before the text. - Add
a.external::after { content: " ↗"; }on a link with classexternal. - Style
.lead::first-letterlarger and teal; style.lead::first-linewithfont-weight: 600. - Add
.card::before { content: ""; display: block; height: 4px; background: #0f766e; }for a top bar.
Common mistakes
- Writing
:beforewhen you meant a state like:hover— remember states use one colon; generated boxes use two - Forgetting
contentso::before/::afternever appear - Putting the only version of a warning or label inside
::after - Applying
::first-letterto an empty or image-only element and expecting magic - Confusing
::first-linewith “first sentence” — wrapping decides the line
Summary
- Pseudo-elements use
::to style a part of an element or a generated box ::before/::afterneedcontent(string or"")::first-letterand::first-linestyle the start of a text block- Keep critical meaning in HTML, not only in generated content
- One colon = pseudo-class; two colons = pseudo-element
- Practice with a quote mark, a link suffix, and a lead paragraph
🧠 Test Your Knowledge
Test Your Knowledge
Challenge yourself with this interactive quiz and see how well you understand the topic
📝 Instructions
- Read each question carefully
- Select the best answer for each question
- You can retake the quiz as many times as you want
- Your progress will be shown at the top