Module 8 · Mastery · Lesson 3 of 5

CSS Specificity & Architecture

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

When your rule "doesn't work," specificity is usually why. Learn the scoring, the !important trap, and the naming conventions that keep 10,000-line stylesheets sane — this is CSS as engineering.

1. The scoring system

Selector partScore columnExample
Inline style1-0-0-0style="…"
ID0-1-0-0#hero
Class / attribute / pseudo-class0-0-1-0.card, :hover
Element / pseudo-element0-0-0-1p, ::before

Compare column by column, left to right — one ID (0-1-0-0) beats any number of classes (0-0-99-0). nav .link:hover scores 0-0-2-1. Ties fall to source order. And !important jumps the whole queue — which is exactly why it breeds more !important; treat it as a last resort, not a tool.

2. Architecture: keeping it flat

CSS — BEM naming keeps specificity uniform
/* Block __Element --Modifier */
.card          { }
.card__title   { }
.card__button  { }
.card--featured{ }

Professional stylesheets stay overridable by staying flat: single-class selectors everywhere, so any rule can be beaten by any later rule. BEM naming encodes structure into the class name instead of the selector chain. Avoid styling IDs; avoid deep descendant chains; group your files base → layout → components → utilities. Modern CSS adds :where(), which contributes zero specificity — handy for resets.

3. Try it yourself

The button stubbornly stays gray because an ID rule outguns your class. Fix it properly: change the #actions button selector into a flat class-based one so .btn-primary can win. (No !important allowed!)

exercise.html — editable

4. Quiz — check your understanding

CSS Specificity & Architecture Quiz

4 questions · pass at 60%

Q1. Which selector wins: #nav a or .nav .list .item a:hover?

0-1-0-1 vs 0-0-3-1: the ID column is compared first and wins outright.

Q2. .card:hover::before scores…

One class + one pseudo-class = 2 in the class column; ::before adds 1 in the element column.

Q3. Why is !important discouraged?

It breaks the normal resolution system — the only counter is another !important.

Q4. In BEM, .card__title is…

Double underscore marks an element belonging to the block; double dash marks modifiers.
🏆
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 →