CSS Specificity Explained Once and For All
Stop fighting the cascade. Understand the specificity scoring system, the stacking order, how !important fits in, and practical rules for styles that don't fight each other.
CSS specificity is responsible for more developer frustration than almost any other CSS concept. The styles aren't applying — why? The answer, almost always, is specificity. Let's untangle it once and for all.
Every selector gets a score based on what it contains. Think of it as three separate digits: (A, B, C).
- A — ID selectors (
#nav). Each one adds 1 to A. - B — Class selectors (
.card), attribute selectors ([type="text"]), pseudo-classes (:hover,:focus). Each adds 1 to B. - C — Element selectors (
div,p,a), pseudo-elements (::before). Each adds 1 to C.
| Selector | A | B | C | Score |
|---|---|---|---|---|
| p | 0 | 0 | 1 | (0,0,1) |
| .card | 0 | 1 | 0 | (0,1,0) |
| .card p | 0 | 1 | 1 | (0,1,1) |
| #nav .link | 1 | 1 | 0 | (1,1,0) |
| style="" | Inline | (1,0,0,0) | ||
Compare from left to right. The first digit that differs wins. (1,0,0) beats (0,5,0). A single ID beats any number of classes.
!important overrides all specificity. It's a specificity escape hatch — not a solution.
/* Bad — using !important to fight a specificity battle */
.button { color: red !important; }
/* Good — fixing the root cause: lower the conflicting selector's specificity */
If you're reaching for !important more than once a month, your CSS architecture has a specificity problem. The fix is flatter selectors and a consistent naming convention like BEM.
- Never use IDs in CSS. Use classes. IDs score (1,0,0) and cause specificity debt that's painful to undo.
- Keep selectors shallow. One or two levels deep at most.
.card .titleis fine..page .section .card .title spanis a problem. - Use BEM or a similar convention.
.card__titleis a single-class selector — easy to override, impossible to conflict. - Use
:where()for zero-specificity resets.:where(h1, h2, h3) { margin: 0; }has a specificity of (0,0,0) — any class can override it.