The Cascade & Specificity
Sooner or later two rules will both try to style the same element in different ways. The "cascade" in Cascading Style Sheets is the set of tie-breaking rules the browser uses to pick a winner.
Rule one: later wins
When two rules have equal weight, the one that appears later in the stylesheet — or later in the page, if you have more than one stylesheet — is the one that takes effect. Nothing fancy, just last one standing:
Swap the order of the two blocks above and the color flips. This is why the order your stylesheets load in — and the order of rules within them — actually matters.
Rule two: specificity beats order
Source order only decides ties. Before that, the browser scores each selector for how specific it is, and the more specific selector wins regardless of which one was written first. Roughly, from weakest to strongest:
- Element selectors —
p,div,h2— the weakest match, since they hit every element of that type. - Class selectors —
.warning— stronger, since they only hit elements you've explicitly tagged. - ID selectors —
#header— stronger still, since an id is meant to be unique to one element.
Here, the element selector is written last, but the class still wins because it scores higher:
An id beats a class the same way. This one has both a class and an id competing for the text color — the id wins no matter which rule is written first:
Combining selectors adds their scores together — .card.featured beats a plain .card, and #sidebar p.note beats a lone .note. You don't need to memorize a point system; just remember the pecking order: id, then class, then element.
The override nobody can beat: !important
Adding !important to a declaration makes it win against nearly anything else targeting that property, no matter how specific the competing selector is:
That power is exactly why !important causes trouble. Once one declaration has it, the only way to override that declaration later is with another !important that's even more specific — and stylesheets that get into that habit turn into a guessing game where nobody's sure which rule will actually apply. It stops the cascade from working the way it's meant to.
!important is almost always to write a more specific selector, or to reorganize so the rule you want to win is simply the more specific one. Save !important for rare situations, like overriding inline styles injected by code you don't control.