Module 8 · Mastery · Lesson 2 of 5

CSS Pseudo-classes & Elements

Advanced ⏱ 25 min2 sections · 1 exercise · 4-question quiz

Pseudo-classes select by state or position; pseudo-elements style parts that don't exist in your HTML. Together they're how CSS decorates, counts, and reacts — often replacing markup and JavaScript entirely.

1. Pseudo-classes: state and structure

CSS — the ones you'll actually use
button:hover        { }
input:focus-visible { outline: 2px solid #5A8AB9; }
li:first-child      { }
li:nth-child(odd)   { background: #F5F7F8; }  /* zebra rows */
li:nth-child(3n)    { }                        /* every 3rd  */
card:not(.featured) { opacity: .8; }

One colon, selecting whole elements by state (:hover, :focus, :checked, :disabled) or position (:first-child, :last-child, :nth-child()). The nth formulas — odd, even, 3n, 3n+1 — pattern-match positions.

2. Pseudo-elements: ::before and ::after

CSS — decoration without markup
.tag::before {
  content: "# ";               /* content is REQUIRED */
  color: #5A8AB9;
}
.link::after {
  content: "";
  display: block; height: 2px;
  background: linear-gradient(90deg, #5A8AB9, #63B29A);
  transform: scaleX(0); transition: transform .25s;
}
.link:hover::after { transform: scaleX(1); }

Two colons, generating a styleable box before or after an element's content — it doesn't render at all without the content property (empty string counts). Badges, dividers, animated underlines, tooltip arrows, gradient hairlines: this site's design leans on ::before/::after constantly.

💡 ::first-letter (drop caps), ::selection (highlight color) and ::placeholder round out the family.

3. Try it yourself

Zebra-stripe the table rows with tr:nth-child(even), and give every .tag a "# " prefix via ::before.

exercise.html — editable

4. Quiz — check your understanding

CSS Pseudo-classes & Elements Quiz

4 questions · pass at 60%

Q1. Pseudo-classes vs pseudo-elements:

One colon = state/structural selection; two colons = generated boxes like ::before.

Q2. What makes ::before/::after actually render?

Without content (even ""), the pseudo-element doesn't exist.

Q3. li:nth-child(odd) selects…

odd matches 1st, 3rd, 5th positions — zebra striping.

Q4. Which selects an input the user has keyboard-focused?

:focus-visible targets focus that should be visibly indicated — the accessible outline hook.
🏆
Quiz passed? You're one step closer to your certificate.

Every lesson quiz you pass (60%+) is saved in your browser and counts toward the CSSmatic Certificate of Completion.

Track my progress →