Concept · The browser

The cascade and specificity

When two rules disagree: origin, layers, specificity, then order — and why !important is a smell.

3 minspecificity!importantcascade layers@layer

Several CSS rules often set the same property on the same element. The cascade decides which one wins by comparing these criteria in order. Each one is only a tie-breaker for the one before it.

  1. Origin and importance. Normal author styles beat browser defaults. !important declarations beat normal ones.
  2. Cascade layers (@layer). Rules in later layers beat earlier ones, and styles outside any layer beat all layers.
  3. Specificity. The more specific selector wins.
  4. Order. If everything else ties, the rule that appears last wins.

Inline style="" sits above every selector, so only !important beats it.

Specificity

Count three things in a selector, written as (IDs, classes, elements):

SelectorSpecificity
p(0, 0, 1)
.card p(0, 1, 1)
.card .title:hover(0, 3, 0) — pseudo-classes and attributes count as classes
#main .title(1, 1, 0)

Compare left to right. One ID beats any number of classes, and one class beats any number of elements. :where() adds zero specificity. :is() and :not() take the specificity of their most specific argument.

css
#sidebar a { color: gray; }      /* (1,0,1) */
.nav-link.active { color: blue; } /* (0,2,0) — loses, even though it's later and more "meaningful" */

Keeping it manageable

  • Style with single classes. Keep specificity flat and low, so order decides and order is easy to reason about. Methodologies like BEM, CSS Modules and utility classes (Tailwind) all do this.
  • Avoid IDs in selectors. One ID forces every override after it into a specificity arms race.
  • Treat !important as a smell. It usually covers up a specificity problem, and the only way to override it is another !important. Reasonable uses are utility classes that must always win, and overriding third-party inline styles.
  • Use @layer to make precedence explicit, for example @layer reset, base, components, utilities;. Then a later layer always wins, whatever its specificity.

Inheritance is separate. Properties like color and font pass down to children when nothing sets them, but any rule that targets the child, however weak, beats an inherited value.

Learn it in depth