CSS Cascade Origin Levels

CSS cascade origin order — UA, user, author, animation, !important — with layer position.

Reference for the CSS cascade algorithm origin and layer precedence, from user-agent and user styles through author styles, cascade layers, animations and the !important reversal, ranked highest to lowest priority.

Does the cascade run before or after specificity?

Origin and importance are checked first. Only when two declarations share the same origin and importance does the cascade fall through to cascade layers, then specificity, then source order. So a high-specificity author rule still loses to a user-agent !important rule.

What the cascade decides

When several CSS declarations set the same property on the same element, the cascade picks the winner. Before specificity or source order ever come into play, the cascade first sorts declarations by their origin (who wrote them) and importance (normal vs !important). Getting this order right explains why a heavily-specific author rule can still lose to a humble user-agent default marked !important.

How it works

The cascade compares declarations top to bottom through these tiers (highest priority first):

  1. Transitions
  2. User-agent !important
  3. User !important
  4. Author !important
  5. CSS animations
  6. Author normal
  7. User normal
  8. User-agent normal

The key insight is the !important reversal: for normal declarations the order is author over user over user-agent, but for !important declarations it flips to user-agent over user over author. This protects user and accessibility overrides. Cascade layers (@layer) subdivide the author tiers, and only when two declarations tie on all of the above does the engine fall through to specificity and then source order.

Tips and notes

A transition always wins so animation never jams behind a static !important rule. Within author styles, unlayered declarations beat layered ones for normal rules — but that too reverses under !important. If a rule “won’t apply” despite high specificity, check whether something higher in this origin table (often a user-agent or user !important) is quietly outranking it. The comparison tool below resolves any two declarations for you.