Understanding Specificity
When two CSS rules target the same element and set the same property to different values, the browser needs a tiebreaker. That tiebreaker is specificity — a scoring system based on the type of selectors used.
Understanding specificity is the difference between debugging CSS confidently and guessing at random.
The specificity score
Section titled “The specificity score”Every selector has a specificity score, calculated from three tiers. Think of it as a three-digit number where each tier is a separate counter: (A, B, C).
| Tier | What it counts | Score |
|---|---|---|
| A | ID selectors | 1, 0, 0 |
| B | Class selectors, pseudo-classes, attribute selectors | 0, 1, 0 |
| C | Type selectors, pseudo-elements | 0, 0, 1 |
The universal selector (*) and combinators ( , >, +, ~) contribute zero to specificity.
Higher tier wins regardless of the count in lower tiers. One ID (1,0,0) beats any number of classes (0,99,0).
Calculating specificity
Section titled “Calculating specificity”Count the selectors from each tier:
/* One type selector → (0, 0, 1) */h1 { color: red; }
/* One class selector → (0, 1, 0) */.heading { color: blue; }
/* One ID selector → (1, 0, 0) */#main-title { color: green; }An <h1> with class="heading" and id="main-title" will be green — the ID wins.
More complex selectors:
/* nav a — one type + one type → (0, 0, 2) */nav a { color: white; }
/* .site-nav a — one class + one type → (0, 1, 1) */.site-nav a { color: #f5f0eb; }
/* .site-nav .nav-link — two classes → (0, 2, 0) */.site-nav .nav-link { color: #b8d4a0; }.site-nav a beats nav a because (0, 1, 1) beats (0, 0, 2).
Inline styles
Section titled “Inline styles”Inline styles beat all selector-based rules. They score in a fourth tier: (1, 0, 0, 0) — higher than any ID.
<h1 style="color: red;">Summit Trail Outfitters</h1>This is why inline styles override your stylesheet — and another reason to avoid them.
!important
Section titled “!important”!important placed after a declaration value forces it to win, ignoring all specificity.
h1 { color: green !important;}An !important rule beats everything except another !important rule with higher specificity. When two !important rules conflict, specificity decides between them normally.
Do not use !important to fix specificity problems. It breaks the cascade permanently, makes your stylesheet harder to maintain, and forces the next developer to use more !important to override you. When you feel the urge to reach for !important, the real problem is usually a selector that is too specific — fix the selector instead.
Debugging specificity in DevTools
Section titled “Debugging specificity in DevTools”Open DevTools (F12) and click an element. In the Styles panel:
- Rules are listed from highest to lowest specificity
- Overridden declarations appear with a strikethrough
- Hover over a selector to see its specificity score as a tooltip in some browsers
When a style is not applying, look for the strikethrough in DevTools — something with higher specificity is winning.
Practical specificity management
Section titled “Practical specificity management”The most common specificity trap: mixing type selectors in stylesheets with class selectors in components.
/* Broad rule using a type selector — (0, 0, 1) */a { color: #2c4a1e;}
/* Component rule using a class — (0, 1, 0) */.site-nav a { color: #f5f0eb;}.site-nav a has higher specificity than a, so nav links will be light — as intended.
The practical guidance for keeping specificity manageable:
- Use type selectors for base/reset styles
- Use class selectors for components — avoid IDs in stylesheets
- Keep selectors as short as possible —
.card h3rather thanmain section .card h3 - Never use
!importantto fix a conflict — fix the selector
Exercise
Section titled “Exercise”In your Summit Trail Outfitters stylesheet, create a deliberate specificity conflict to see it in action:
- Write a general rule for
h3with a red color:
h3 { color: red;}- Write a class rule for
.tour-namewith the correct green:
.tour-name { color: #2c4a1e;}-
Open the browser. Tour card headings should be green, not red — the class selector wins.
-
Open DevTools, click a
.tour-nameelement. In the Styles panel, confirmcolor: redfrom theh3rule is struck through, andcolor: #2c4a1efrom.tour-nameis applied. -
Remove the
color: redtest rule from your stylesheet after confirming the behavior.
- Specificity is a three-tier scoring system: ID (A) → class/pseudo-class (B) → type/pseudo-element (C).
- A rule with any score in tier A beats any score in tier B or C.
- The universal selector and combinators do not contribute to specificity.
- Inline styles have a fourth tier — they beat everything selector-based.
!importantbreaks the cascade; avoid it. Fix the selector instead.- DevTools shows specificity conflicts as strikethrough declarations in the Styles panel.
- Keep selectors short; prefer classes over IDs to stay in control of specificity.