</> ConvertAtlas Developer Tools
Level 2 · Intermediate — Layout & Responsive Lesson 22 Intermediate 14 min

Pseudo-Classes and Pseudo-Elements

Style states and generated content with :hover, :focus, :nth-child, ::before and ::after.

Pseudo-classes and pseudo-elements let you style things you cannot target with normal selectors — interaction states, specific items in a list, and decorative content generated by CSS itself. They are everywhere in professional CSS.

Pseudo-classes: styling states

A pseudo-class targets an element in a particular state, written with a single colon. You already met <code>:hover</code> and <code>:focus</code>. Others select by position or condition: <code>:first-child</code>, <code>:last-child</code>, <code>:nth-child()</code>, <code>:not()</code> and <code>:checked</code>.

Pseudo-classSelects
:hover / :focusMouse over / keyboard focus
:nth-child(odd)Every odd item (zebra stripes)
:first-child / :last-childFirst / last in a parent
:not(.x)Everything except .x
:checkedA checked checkbox or radio
HTML
<ul class="list"><li>One</li><li>Two</li><li>Three</li><li>Four</li></ul>
CSS
.list{list-style:none;padding:0}
.list li{padding:10px 14px}
.list li:nth-child(odd){background:#e0f2fe}
.list li:hover{background:#bae6fd}
Result
Zebra striping with :nth-child(odd) + hover.

Pseudo-elements: generated content

A pseudo-element, written with two colons, styles a specific part of an element or inserts content. <code>::before</code> and <code>::after</code> add generated content (they need a <code>content</code> property). They are perfect for icons, decorations and badges without extra HTML.

HTML
<p class="tip">Pro tip text here</p>
CSS
.tip{padding:10px 14px;background:#fef3c7;border-radius:8px}
.tip::before{content:'💡 ';}
Result
::before inserts an icon with no extra HTML.

A common real use: custom underlines

HTML
<a href="#" class="link">Fancy link</a>
CSS
.link{position:relative;text-decoration:none;color:#2563eb}
.link::after{content:'';position:absolute;left:0;bottom:-3px;width:100%;height:2px;background:#2563eb;transform:scaleX(0);transition:transform .2s}
.link:hover::after{transform:scaleX(1)}
Result
A pseudo-element underline that animates on hover.
Common mistake
Don't
.tip::before { color: red; }
Do
.tip::before { content: ''; color: red; }

Forgetting the content property on ::before / ::after — without it, nothing renders at all (even content: "" is required).

Best practice

Use single colon for pseudo-classes (:hover) and double for pseudo-elements (::before) — the double-colon syntax makes the distinction clear. Reach for ::before/::after for decoration so your HTML stays clean.

Try it yourself

Make a list with zebra striping using :nth-child(odd), then add a ::before icon to a "note" paragraph, and build an animated underline link using ::after.

Quick quiz

1. Which selects every odd list item?

2. What is required on ::before to render?

3. Pseudo-elements use…

Key takeaways
  • Pseudo-classes (:hover, :nth-child) target states and positions.
  • Pseudo-elements (::before, ::after) add generated content — content is required.
  • Use them for decoration so your HTML stays clean.
  • Single colon = pseudo-class, double colon = pseudo-element.