Frontend Master

JavaScript Curriculum

Specificity and the Cascade
+60 XP

Specificity and the Cascade

medium
~30 min·60 XP

A developer added a button style last month. Now you're trying to override it but nothing works. This is a cascade problem — and once you understand specificity scoring, you'll never be stuck again.

Specificity and the Cascade

When two CSS rules target the same element and set the same property, the browser has to pick one. It uses the cascade — an algorithm with four factors: origin, specificity, source order, and inheritance. Understanding it turns CSS debugging from frustration into logic.

Specificity — Selector Weight

Every selector has a score. Higher score wins. The score is expressed as three numbers: (a, b, c):

specificity-calculator.css
Selector A
IDs (a)0
Classes / attrs (b)1
Elements (c)1
(0,1,1) = 11
Selector B
IDs (a)1
Classes / attrs (b)0
Elements (c)1
(1,0,1) = 101
Selector B wins — higher specificity takes effect

Click any quick-pick selector to paste it into Selector A, then click again for B.

💡The specificity scoring system
IDs count as (1,0,0). Classes, attributes, and pseudo-classes count as (0,1,0). Elements and pseudo-elements count as (0,0,1). Compare left to right — one ID beats any number of classes. The universal selector (*) and combinators (+, >, ~) contribute zero. Inline styles are (1,0,0,0) — above the ID column entirely.

The Cascade — Priority Order

Beyond specificity, the cascade has a layer order that determines which rules even compete:

cascade-order.css
Priority 1/4

Every browser ships a default stylesheet (user-agent styles). h1 is big, links are blue, margins exist. These are overridden by everything else.

/* browser default (simplified) */
h1 { font-size: 2em; font-weight: bold; }
a  { color: blue; text-decoration: underline; }
p  { margin: 1em 0; }
⚠️!important is a last resort, not a tool
Every time you use !important, you're borrowing complexity from the future. The next developer who needs to override your rule has no clean option — they must use !important too, escalating the arms race. Reserve it for genuine exceptions: overriding third-party styles, utility classes that must always apply, accessibility overrides.

Inheritance — What Passes Down the DOM

Not all CSS properties inherit from parent to child. Knowing which ones do saves repetitive declarations:

inheritance.css

Click any property to learn whether it inherits and why.

✓ inherited = passes down the DOM tree automatically
✗ not inherited = must set explicitly on each element

Typography properties (color, font-*) almost always inherit. Box model properties (margin, padding, border) never do.

ℹ️inherit, initial, unset
Three special keyword values control inheritance explicitly. inherit forces a property to take its parent's value. initial resets it to the browser default. unset behaves like inherit for inherited properties and initial for non-inherited ones — useful for resetting everything cleanly.

Your Challenge

Debug a specificity conflict and refactor a stylesheet that abuses !important into clean, predictable rules.

Challenge

Given three competing rules for a .card p element — one element rule, one class rule, one ID rule — predict which wins. Then refactor a style sheet that relies on !important by lowering specificity instead.

specificitycascadeinheritanceimportantsource-orderselector-weightbrowser-defaultsinline-stylesinheritinitialunsetrevert
Specificity and the Cascade | Nexus Learn