CSS · Architecture

Specificity and Inheritance

“Why isn’t my CSS working?” Nine times out of ten, another rule is winning. This lesson explains exactly how CSS chooses — so you will never have to guess again.

Advanced 6 min Lesson 21 of 26 Runnable examples
Before you start:Selectors
0/26 in CSS
On this page · 6 min · Advanced

Learning objectives#

  • Explain the cascade order
  • Calculate specificity scores
  • Know which properties inherit
  • Use inherit, initial and unset
  • Avoid !important wars

Explanation#

When several rules set the same property on an element, CSS picks a winner in this order: importance (!important), then specificity, then source order (later wins).

Specificity is a score of three columns (ids, classes, elements). #nav = 1-0-0; .menu a:hover = 0-2-1; p = 0-0-1. Compare column by column, left to right: one id beats any number of classes.

Classes, attributes ([type]) and pseudo-classes (:hover) all count in the middle column. Elements and pseudo-elements count in the right column. * counts nothing. Inline style beats all selectors.

Inheritance: text-related properties (color, font, line-height) pass from parent to children automatically. Box properties (margin, border, background, width) do not.

inherit forces inheritance, initial resets to the CSS default, unset does whichever is natural for the property.

Code example: Who wins?#

HTMLWho wins? Runnable
<style>
  p { color: gray; }                 /* 0-0-1 */
  .note { color: green; }            /* 0-1-0 → beats p */
  #special { color: purple; }        /* 1-0-0 → beats .note */
  .box p.note { color: orange; }     /* 0-2-1 */
  .note { color: teal; }             /* 0-1-0, later than first .note → beats it, but not 0-2-1 */


  .box { color: crimson; font-family: Georgia, serif; border: 2px solid crimson; padding: 8px; }
  .box a { color: inherit; }         /* links normally ignore parent colour */
</style>


<p>Plain paragraph → gray</p>
<p class="note">.note → teal (later .note wins)</p>
<p class="note" id="special">#special → purple (id wins)</p>


<div class="box">
  <p class="note">.box p.note → orange (most specific)</p>
  Box text is crimson and serif. <a href="#">This link inherits crimson</a>.
  <span>Spans inherit the font and colour but not the border.</span>
</div>
Expected output
Each line shows its colour and the reason: gray, teal, purple, orange, then crimson text inside a bordered box where the link and span inherit colour and font but not the border.
Opens this example in the full playground

Step-by-step explanation#

  1. p alone has the lowest specificity.
  2. Two .note rules tie on specificity, so the later one (teal) wins.
  3. #special has an id, so it beats every class-based rule.
  4. .box p.note has two classes and one element (0-2-1), beating plain .note.
  5. Text properties inherit from .box; the border does not.
  6. Links have their own browser colour, so color: inherit makes them use the parent’s.

Real-world use case#

When a style “does not apply”, open DevTools → Styles. Overridden declarations are crossed out, and hovering a selector shows its specificity.

Common mistakes#

Reaching for !important

!important wins today, but the next fix needs another !important. Lower the specificity of the original rule instead.

Styling with ids

An id selector is so strong that overriding it needs another id or !important. Use classes.

Expecting margin or border to inherit

Only text-ish properties inherit. Box properties must be set on each element.

Best practices#

  • Keep specificity low and flat (single classes)
  • Avoid ids and !important in stylesheets
  • Order stylesheets general → specific
  • Use :where() to write zero-specificity defaults

Remember this#

Specificity = (ids, classes, elements). Compare left to right, like version numbers.

Same score? The last rule wins.

Text inherits (color, font). Boxes don’t (margin, border, background).

Practice exercise#

Your task: Calculate the specificity of: (a) nav ul li a (b) .menu .item:hover (c) #header .logo

Need a hint?
Count ids, then classes/pseudo-classes, then elements.
Show solution
Text Illustrative
(a) nav ul li a       → 0-0-4
(b) .menu .item:hover → 0-3-0
(c) #header .logo     → 1-1-0   ← strongest

Mini quiz#

Specificity and Inheritance quizMultiple choice Question 1 of 3

Which selector has the highest specificity?

Score so far: 0/0

Want more? Practise all CSS MCQs · CSS interview questions

My notes#

Saved in this browser.

Progress is saved in this browser. Sign in to sync.