CSS Specificity Explained in a Fun Way
A fun, beginner-friendly guide to understanding CSS specificity with practical examples and easy-to-remember rules. - 22 Sept 2025
3 min read

CSS Specificity: The Hunger Games of Stylesheets
If you’ve ever wondered why your color: red;
doesn’t show up, even though you wrote the CSS rule correctly, you’ve met the tricky world of CSS specificity. Think of it as a points game where selectors battle to decide which style wins.
Meet the Players
-
Element selectors (
p
,h1
,div
) → Weak but common. Score: 1 point. -
Class selectors (
.button
), attributes ([type="text"]
), pseudo-classes (:hover
) → Medium strength. Score: 10 points. -
ID selectors (
#main
) → Strong. Score: 100 points. -
Inline styles (
style="color: blue"
) → Overpowered. Score: 1000 points.
The Specificity Scoreboard
When two rules conflict, the browser adds up their specificity scores:
inline styles > IDs > classes > elements
That means:
#header nav ul li a
beats.nav-link
- But inline styles beat them all
Example in Action
p {
color: blue; /* Score: 1 */
}
.article p {
color: green; /* Score: 10 + 1 = 11 */
}
#content .article p {
color: orange; /* Score: 100 + 10 + 1 = 111 */
}
<p id="content" class="article" style="color: red">
May the odds be ever in your favor!
</p>
Final color: red, because inline style wins with a score of 1000.
Plot Twists
- Universal selector (
*
): worth zero points. - !important: skips the queue, but overuse leads to chaos.
- Inheritance: only certain properties (like
color
) pass down; margins don’t.
Practical Scenarios (and quick fixes)
1) Overriding a design system button
Your design system ships .btn.primary { background: #3b82f6; }
, but you wrote .primary { background: black; }
and nothing changes.
<button class="btn primary">Save</button>
/* Library */
.btn.primary { background: #3b82f6; }
/* Yours (too weak and/or loses by order) */
.primary { background: black; }
/* Quick fix: match the system's specificity (class + class) */
.btn.primary { background: black; }
If you control the library layer, prefer a theming token instead of increasing specificity.
2) Hover not taking effect
<a class="link">Read more</a>
.card a.link { color: #2563eb; } /* 10 + 1 + 10 = 21 */
a:hover { color: #ef4444; } /* 1 + 10 = 11 (loses) */
/* Fix: target the same element at equal/greater specificity */
.card a.link:hover { color: #ef4444; } /* 21 + 10 = 31 */
/* Better: reduce the earlier selector if possible */
.card a { color: #2563eb; }
3) ID beating utilities (e.g., Tailwind)
<div id="hero" class="text-gray-500 md:text-gray-900">Hello</div>
#hero { color: #333; } /* 100 beats utility classes (10) */
Result: the text stays #333
regardless of utilities. Fixes:
- Prefer classes over IDs for styling.
- If refactor isn’t possible, scope the ID to contain classes and style the class instead:
#hero .text-gray-900 { color: #111; }
- Or, better, move color to a CSS variable and set it via utilities.
4) Inline style blocking theme
<h1 style="color: green">Title</h1>
.theme-dark h1 { color: white; } /* loses to inline (1000) */
Fixes:
- Remove the inline color and let CSS control it.
- Or use a variable inline and theme it:
<h1 style="color: var(--heading-color)">Title</h1>
:root { --heading-color: #111; } .theme-dark { --heading-color: #fff; }
5) Keep selector specificity low with :where()
When building components, deep selectors can snowball specificity:
.nav ul li a { color: #111; } /* 10 + 1 + 1 + 1 = 13 */
Use :where()
to avoid adding specificity:
.nav :where(a) { color: #111; } /* still just 10 from .nav */
This makes your styles easier to override downstream.
6) Quick debugging checklist
- Open DevTools, inspect the element, and check the Styles panel.
- Compare selector specificities and the cascade order.
- Look for inline styles and
!important
flags. - Prefer reducing earlier specificity before adding more.
Takeaway
Specificity isn’t magic—it’s math. Elements are weak, classes are stronger, IDs are powerful, and inline styles dominate. If your CSS isn’t working, check the specificity scoreboard before pulling your hair out.