Tutorials Logic, IN info@tutorialslogic.com

CSS Specificity Cascade How It Works

What is Specificity?

Specificity explains why one CSS rule wins over another. When styles do not apply as expected, the issue is often not that CSS is broken; it is that another selector is stronger or appears later in the cascade.

The goal is not to write the strongest selector. The goal is to write selectors that are strong enough to target the right element but still easy to override later.

When multiple CSS rules target the same element, the browser uses specificity to determine which rule wins. Specificity is calculated as a score - the rule with the highest score is applied.

Specificity is calculated using four categories (A, B, C, D):

Category What counts Score
A - Inline styles style="..." attribute 1,0,0,0
B - ID selectors #id 0,1,0,0
C - Class, attribute, pseudo-class .class, [attr], :hover 0,0,1,0
D - Element, pseudo-element div, p, ::before 0,0,0,1

Specificity Calculation Examples

Specificity Calculation Examples
/*
 * Specificity scores (A, B, C, D):
 *
 * *                    -> 0,0,0,0  (universal)
 * p                    -> 0,0,0,1  (element)
 * .class               -> 0,0,1,0  (class)
 * #id                  -> 0,1,0,0  (ID)
 * style=""             -> 1,0,0,0  (inline)
 *
 * p.class              -> 0,0,1,1  (element + class)
 * div p                -> 0,0,0,2  (2 elements)
 * .nav .link           -> 0,0,2,0  (2 classes)
 * #header .nav a       -> 0,1,1,1  (ID + class + element)
 * #header #nav         -> 0,2,0,0  (2 IDs)
 */

/* Which color wins? */
p { color: blue; }           /* 0,0,0,1 */
.text { color: green; }      /* 0,0,1,0 - wins over p */
#main { color: red; }        /* 0,1,0,0 - wins over .text */
/* inline style="color: orange" - wins over #main */

/* !important - overrides everything (use sparingly!) */
p { color: blue !important; }  /* wins even over inline styles */

/* Specificity tie - last rule wins */
.btn { background: blue; }
.btn { background: red; }   /* wins - same specificity, later in file */

/* Practical: avoid high specificity chains */
/* BAD - hard to override */
#sidebar .widget ul li a { color: blue; }

/* GOOD - low specificity, easy to override */
.sidebar-link { color: blue; }

The Cascade

The cascade determines which CSS rule applies when multiple rules conflict. It considers three factors in order:

Low-specificity CSS is easier to maintain. Utility classes, component classes, and modern helpers like :where() can keep selectors predictable.

  • Origin and importance - browser defaults < user styles < author styles < !important
  • Specificity - higher specificity wins
  • Source order - when specificity is equal, the last rule in the file wins

Inheritance and the Cascade

Inheritance and the Cascade
/* Inheritance - some properties inherit from parent */
/* Inherited: color, font-*, line-height, text-*, visibility */
/* Not inherited: margin, padding, border, background, width, height */

body {
    color: #333;        /* all text inherits this color */
    font-family: Arial; /* all text inherits this font */
}

/* inherit keyword - force inheritance */
.child {
    border: inherit;    /* inherit border from parent (not normally inherited) */
    color: inherit;     /* explicitly inherit color */
}

/* initial keyword - reset to browser default */
.reset {
    color: initial;     /* resets to browser default (usually black) */
    font-size: initial; /* resets to browser default (usually 16px) */
}

/* unset keyword - inherit if inheritable, else initial */
.unset {
    color: unset;       /* inherits (color is inheritable) */
    margin: unset;      /* initial (margin is not inheritable) */
}

/* revert keyword - reset to browser stylesheet value */
.revert {
    all: revert;        /* reset ALL properties to browser defaults */
}

/* Specificity best practices */
/* 1. Keep specificity low - use classes, not IDs */
/* 2. Avoid !important - it breaks the cascade */
/* 3. Use :is() and :where() for complex selectors */

/* :is() - matches any selector in list, takes highest specificity */
:is(h1, h2, h3) { margin-top: 0; }

/* :where() - same but ZERO specificity (easy to override) */
:where(h1, h2, h3) { margin-top: 0; }

CSS Specificity Cascade How It Works CSS fallback case

CSS Specificity Cascade How It Works CSS fallback case
.lesson-box:empty::before {
  content: "CSS Specificity Cascade How It Works: add visible content";
}
Before you move on

CSS Specificity Cascade How It Works Mastery Check

5 checks
  • Prefer class selectors for components instead of long descendant chains.
  • Avoid IDs in CSS unless you truly need very high specificity.
  • Use DevTools to see which rule is crossed out and which rule wins.
  • Use :where() to group selectors without increasing specificity.
  • Use !important only as a last resort or for deliberate utility overrides.

CSS Questions Learners Ask

No. Source order matters only after importance and specificity are equal.

IDs have high specificity, which makes later overrides harder.

It is not always bad, but it should be used deliberately because it can make future overrides difficult.

Browse Free Tutorials

Explore 500+ free tutorials across 20+ languages and frameworks.