The Cascade, Specificity & Inheritance

When two rules disagree, the cascade picks a winner using origin, specificity, and source order.

CSS6 min readConcept 4 of 43

Three layers of conflict resolution

CSS properties are declarations, and multiple declarations can target the same element. The **cascade** is the algorithm that decides which one wins. It applies three criteria in order: **origin and importance**, then **specificity**, then **source order**.

**Inheritance** is separate but related: some CSS properties flow down the DOM tree by default (like color and font-size), so child elements can pick up values from their ancestors without being explicitly targeted.

Predictable styles require understanding all three

Specificity is the most common source of 'why is my style not applying?' bugs. The fix is rarely !important; it is usually writing a more specific selector or restructuring the stylesheet order.

Understanding inheritance tells you which properties you can set once on a parent (<body>) and rely on children to pick up, versus which you must repeat on every targeted element.

How each layer works

**Origin:** The browser has its own default stylesheet (User Agent). Author styles (your CSS) override UA styles. !important reverses this: !important author beats !important user, but should be a last resort because it breaks the normal cascade.

**Specificity:** Each selector earns a score. Inline style= = (1,0,0,0). An id #x = (0,1,0,0). A class .x, attribute [x], or pseudo-class :hover = (0,0,1,0). A type div or pseudo-element ::after = (0,0,0,1). Universal * and combinators contribute 0. Add up all the scores; higher tuple wins. You cannot 'overflow' from type to class: ten classes (0,0,10,0) still lose to one id (0,1,0,0).

**Source order:** When origin and specificity are equal, the declaration that appears later in the stylesheet wins. This is why a <style> block placed after a <link> can override it.

**Inheritance:** Properties like color, font-family, font-size, line-height, text-align inherit by default. Layout properties like margin, padding, background, border, width do not. Use inherit to force inheritance, initial to reset to the CSS spec default, or unset to get the natural default (inherit if inheritable, else initial).

Try it

Watch the specificity scoreboard light up, see conflicting rules resolved, and observe which properties inherit down the tree.

Specificity scoreboard

SelectorInlineIDClsTypeNote
p0001type selector
.card:hover0020class + pseudo-class
#hero .titlewinner0110id + class

Specificity is compared column by column, left to right. The first column that differs decides the winner.

Cascade conflict resolution

.card p { color: #34d399; }

Specificity: (0,0,1,1)

Applied

p { color: #94a3b8; }

Specificity: (0,0,0,1)lost: lower specificity

Overridden

The <p> inside .card renders in emerald. Higher specificity wins.

Inheritance: what flows down the tree?

Parent element (styles set here)

colorinheritsInherited: #a5f3fc
font-sizeinheritsInherited: 1rem
backgrounddoes not inheritNot inherited: transparent
margindoes not inheritNot inherited: 0
borderdoes not inheritNot inherited: none

Text-related properties (`color`, `font-*`, `line-height`) inherit. Box-model properties (`margin`, `padding`, `background`, `border`) do not. Use inherit to force any property to inherit.

Check yourself

Pick an answer to lock it in, then read why. Getting one wrong is part of how it sticks.

  1. 1Two rules both set `color` on the same `<p>`. Rule A uses `.card p` (0,0,1,1). Rule B uses `p` (0,0,0,1). Which wins?
  2. 2Which CSS keyword forces an element to inherit a property from its parent, even if that property does not inherit by default?
  3. 3What is the specificity score for this selector: `#nav .link:hover`?

Remember this

  • Cascade order: origin/importance first, then specificity, then source order.
  • Specificity tuple: (inline, id, class/attr/pseudo-class, type/pseudo-element). Higher = wins.
  • Properties like color and font-size inherit by default. Layout props like margin do not.
  • Use inherit, initial, unset to control inheritance explicitly. Avoid !important except as a last resort.

Done with this concept?

Mark it complete to track your progress. No login needed.