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:

Try it yourself
Result

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 selectorsp, 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:

Try it yourself
Result

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:

Try it yourself
Result

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:

Try it yourself
Result

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.

Note: a better fix than reaching for !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.