CSS: Specificity

By Xah Lee. Date: .
xtodo

CSS Specificity Tutorial

ai answer

CSS specificity is the browser's rule for deciding which style "wins" when multiple CSS declarations target the same element. Think of it as a scoring system — the declaration with the highest specificity score gets applied.

If two declarations have exactly the same specificity, the one that appears later in the stylesheet (or the last one in the cascade) wins.


1. How Specificity is Calculated

The browser calculates specificity as a four-part tuple:

(inline styles, IDs, classes/attributes/pseudo-classes, elements/pseudo-elements)
Component Score Example Selectors
Inline styles 1,0,0,0 <p style="color: red;">
ID selectors 0,1,0,0 #header, #nav
Classes, attributes, pseudo-classes 0,0,1,0 .nav, [type="text"], :hover, :nth-child
Elements & pseudo-elements 0,0,0,1 p, div, ::before, ::after

Important: Specificity is compared left to right.
0,1,0,0 (one ID) beats 0,0,99,99 (99 classes + 99 elements).


2. Quick Reference Table of Common Selectors

Selector Specificity Score (as tuple)
* 0 (0,0,0,0)
p 1 (0,0,0,1)
.class 10 (0,0,1,0)
p.class 11 (0,0,1,1)
#id 100 (0,1,0,0)
#id p 101 (0,1,0,1)
#id .class 110 (0,1,1,0)
style="..." (inline) 1000 (1,0,0,0)
p:hover 11 (0,0,1,1)
::before 1 (0,0,0,1)
:not(.class) 10 (0,0,1,0)
:is(.class, #id) 100 (0,1,0,0)

3. Real-World Examples

Example 1: Basic Conflict

HTML

Hello World

CSS

p { color: red; }                    /* (0,0,0,1) */
.message { color: blue; }            /* (0,0,1,0) */
#greeting { color: green; }          /* (0,1,0,0) */

Result: Text is green — the ID wins.

Example 2: Multiple Classes vs ID

#sidebar .box p { color: red; }      /* (0,1,1,1) = 111 */
.sidebar .box p { color: blue; }     /* (0,0,2,1) = 021  */

Even though the second rule has more classes, ID wins.

Example 3: Inline Styles Beat Everything (almost)

HTML

Hello

p.text#text { color: purple; }   /* (0,1,1,1) — very high! */

Result: Still orange — inline styles win.


4. The !important Exception

!important overrides specificity completely (except for another !important with higher specificity or later in the cascade).

p { color: red !important; }     /* beats everything below */
#id .class p { color: blue; }

Warning: Overusing !important makes your CSS hard to maintain. Use it only as a last resort (e.g., third-party library overrides).


5. Modern Specificity Tools (:is(), :where(), :has())

CSS now has smarter pseudo-classes that help control specificity:


6. Best Practices (How to Write Maintainable CSS)

  1. Avoid IDs for styling — they have very high specificity.
  2. Prefer classes — they are reusable and have medium specificity.
  3. Keep specificity low — use the simplest selector possible.
  4. Use BEM, SMACSS, or utility classes (Tailwind) to stay flat.
  5. Never use !important in your main stylesheet (only for overrides).
  6. Organize your CSS so more specific rules come later when needed.

Golden Rule:

"Write CSS as if someone else will have to maintain it — including future you."


7. How to Debug Specificity in Browser DevTools

  1. Right-click an element → Inspect.
  2. In the Styles pane, you'll see all applied rules.
  3. Rules that are crossed out lost due to specificity (or cascade order).
  4. Chrome/Firefox now show a small specificity score next to each selector (e.g., 0-1-1).

8. Quick Quiz (Test Yourself)

HTML: <button class="btn" id="submit">Submit</button>

Which color wins?

button { color: red; }                    /* A */
.btn { color: blue; }                     /* B */
#submit { color: green; }                 /* C */
.btn#submit { color: purple; }            /* D */

Answer: purple (D = 0,1,1,1)

Try writing your own examples and checking them in the browser!


You now understand CSS specificity completely.
Next step: practice by refactoring a messy stylesheet to use lower specificity.

Happy styling! 🚀

If you want:

CSS, Advanced