CSS Specificity Hierarchy
In this page:
Compound Selector Specificity Adds Up
A compound selector like div.card.featured combines an element, and two classes, and its specificity is the sum of each part: one element point plus two class points. Developers often underestimate how quickly specificity accumulates when selectors get chained together.
Example: Compound Selector Specificity Adds Up
<style>
div.card { color: black; }
div.card.featured { color: gold; }
</style>
<div class="card featured">Two classes plus an element: highest specificity wins</div>
The :where() Zero-Specificity Trick
The :where() pseudo-class wraps a selector list but contributes zero specificity of its own, unlike :is() which takes the specificity of its highest-specificity argument. This makes :where() useful for writing default/reset styles that are trivially easy for any other rule to override.
Example: The :where() Zero-Specificity Trick
<style>
:where(.reset) p { color: black; }
.card p { color: blue; }
</style>
<div class="reset card"><p>Trivially overridden by any other rule</p></div>
Attribute and Pseudo-Class Selectors Count as Classes
Attribute selectors like [type="text"] and pseudo-classes like :hover or :nth-child() all count at the same specificity level as a regular class selector, one point each. This is easy to forget when a :hover rule unexpectedly fails to override a class-based rule of equal weight.
Example: Attribute and Pseudo-Class Selectors Count as Classes
<style>
.field { border-color: gray; }
[type="text"] { border-color: blue; }
</style>
<input type="text" class="field">
Debugging Specificity Conflicts in DevTools
Browser DevTools shows every matching CSS rule for a selected element with strikethrough on any declaration that lost to a higher-specificity or later rule. Reading this panel from top to bottom is the fastest real-world way to diagnose why a style is not applying, rather than guessing.
Example: Debugging Specificity Conflicts in DevTools
<style>
p { color: black; }
.text { color: green; }
</style>
<p class="text">DevTools shows the losing rule with a strikethrough</p>
Inline Styles and !important Interaction
An inline style attribute normally outranks every selector in a stylesheet regardless of specificity, since it is treated as specificity (1,0,0,0). However, !important on a stylesheet rule outranks even inline styles, making !important genuinely the highest-priority override in the entire specificity system.
Example: Inline Styles and !important Interaction
<style>
p { color: green !important; }
</style>
<p style="color: orange;">!important outranks even this inline style</p>
Chapter Quiz — Complete all 22 topics to unlock
0/22 topics done
Complete these topics first:
- CSS Combinators
- CSS Pseudo-classes
- CSS Pseudo-elements
- CSS Opacity
- CSS Navigation Bar
- CSS Vertical Navbar
- CSS Horizontal Navbar
- CSS Dropdowns
- CSS Advanced Dropdowns
- CSS Image Gallery
- CSS Image Sprites
- CSS Attribute Selectors
- CSS Forms
- CSS Counters
- CSS Specificity
- CSS Specificity Hierarchy
- CSS Variables
- CSS !important
- CSS Box Sizing
- CSS Media Queries
- CSS Pointer Events
- CSS Outline