CSS: Specificity
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 |
- The universal selector
*and combinators (>,+,~, space) have zero specificity. - The pseudo-class
:not()does not add its own score — it takes the specificity of the selector inside it. :is()and:where()have special behavior (we'll cover them later).
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
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:
-
:where()— ignores the specificity of its argument.:where(#header, .nav) p { color: blue; } /* specificity = (0,0,0,1) */ -
:is()— takes the highest specificity inside it.:is(#header, .nav) p { color: blue; } /* specificity = (0,1,0,1) */ -
:has()— very powerful, but specificity is based on the whole selector.
6. Best Practices (How to Write Maintainable CSS)
- Avoid IDs for styling — they have very high specificity.
- Prefer classes — they are reusable and have medium specificity.
- Keep specificity low — use the simplest selector possible.
- Use BEM, SMACSS, or utility classes (Tailwind) to stay flat.
- Never use
!importantin your main stylesheet (only for overrides). - 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
- Right-click an element → Inspect.
- In the Styles pane, you'll see all applied rules.
- Rules that are crossed out lost due to specificity (or cascade order).
- 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:
- More advanced examples
- A specificity calculator tool (with live preview)
- Comparison with Cascade Layers (
@layer)
CSS, Advanced
- CSS: Media Query (Responsive Design)
- CSS: Variable (Custom Property)
- CSS: calc
- CSS: Reset, Default Values
- CSS: Specificity
- CSS: Dark Theme
- CSS: Prevent Right Click
- CSS: Data URI Scheme
- HTML: Protocol-Relative URL
- CSS: Declare Charset
- CSS: Responsive Table
- CSS: Fixed Aspect Ratio
- CSS: Add Icon to Links