The cascade
Cascade and specificity
Predict which declaration wins by considering importance, origin, cascade layers, selector specificity, and source order.
9 minute lesson
Several declarations can target the same property on the same element. The cascade chooses one value before layout begins.
Use this order when debugging:
- relevance: does the selector match and does its media condition apply?
- origin and importance: browser, user, author, animation, or transition
- cascade layer order
- selector specificity
- scoping proximity, when
@scopeis involved - source order when everything else ties
Within ordinary author styles, specificity is a useful comparison:
- IDs outweigh classes.
- classes, attributes, and pseudo-classes outweigh type selectors.
- when specificity ties, the later declaration wins.
p { color: black; }
.intro { color: navy; }
The class wins because both declarations are normal author styles in the same layer, and .intro has greater specificity.
Layers can make priority explicit:
@layer reset, components, utilities;
For normal declarations, a later layer beats an earlier one regardless of selector specificity. Normal unlayered author styles beat all normal layered styles. This is useful for containing third-party CSS.
!important changes cascade priority and reverses layer precedence. It is not “more specificity” and should not be a routine override tool. :where() provides the opposite tool: its selector always contributes zero specificity.
Prefer low-specificity component classes and predictable source order. If you are fighting selectors with more selectors, simplify the structure.
In DevTools, find the crossed-out declaration and read why it lost. Change one factor at a time—layer, selector, then order—until you can predict the winner before refreshing.
Lesson completed