CSS Specificity & Cascade
Specificity determines which CSS rule wins when multiple rules target the same element. Understanding this prevents frustration.
The Cascade
CSS stands for Cascading Style Sheets. Rules cascade based on:
- Source order — Later rules win
- Specificity — More specific rules win
- Importance — !important overrides everything
Specificity Hierarchy
From lowest to highest:
1. Element selectors (p, div, span) → 1 point
2. Class selectors (.class) → 10 points
3. ID selectors (#id) → 100 points
4. Inline styles (style="") → 1000 points
5. !important → Overrides all
Specificity Examples
/* Specificity: 1 */
p {
color: black;
}
/* Specificity: 10 */
.text {
color: blue;
}
/* Specificity: 100 */
#main {
color: red;
}
/* Specificity: 1000 */
<p style="color: green;">Inline style</p>
Result: Green (inline wins)
Calculating Specificity
/* Specificity: 1 (element) */
p { }
/* Specificity: 10 (class) */
.text { }
/* Specificity: 10 (class + class) */
.text.highlight { }
/* Specificity: 100 (ID) */
#header { }
/* Specificity: 110 (ID + class) */
#header .nav { }
/* Specificity: 101 (ID + element) */
#header p { }
/* Specificity: 120 (ID + class + class) */
#header .nav.active { }
/* Specificity: 121 (ID + class + element) */
#header .nav p { }
Source Order
When specificity is equal, later rules win:
/* First rule */
.button {
background-color: blue;
}
/* Second rule (wins) */
.button {
background-color: red;
}
Inheritance
Some properties inherit from parent:
/* Inherited properties */
body {
color: #333; /* Children inherit this */
font-family: Arial; /* Children inherit this */
font-size: 16px; /* Children inherit this */
line-height: 1.6; /* Children inherit this */
text-align: left; /* Children inherit this */
visibility: visible; /* Children inherit this */
}
/* Non-inherited properties */
div {
width: 100px; /* Children don't inherit */
padding: 20px; /* Children don't inherit */
border: 1px solid; /* Children don't inherit */
margin: 10px; /* Children don't inherit */
background: white; /* Children don't inherit */
}
Force Inheritance
/* Force inheritance */
.child {
color: inherit; /* Inherit from parent */
font-size: inherit; /* Inherit from parent */
}
/* Reset to initial value */
.element {
color: initial; /* Reset to browser default */
}
/* Unset (inherit or initial based on property) */
.element {
color: unset;
}
!important
Overrides all specificity:
/* Normal rule */
.button {
background-color: blue;
}
/* !important wins */
.button.urgent {
background-color: red !important;
}
Avoid !important — Makes CSS hard to maintain.
Specificity Conflicts
Problem: Specificity Wars
/* Low specificity */
.text {
color: blue;
}
/* Higher specificity (wins) */
.sidebar .text {
color: red;
}
/* Even higher specificity */
#sidebar .text {
color: green;
}
Solution: Use Classes
/* Good: Consistent specificity */
.text {
color: blue;
}
.text-primary {
color: red;
}
.text-secondary {
color: green;
}
Complete Example: Organizing CSS
/* 1. Reset/Normalize */
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
/* 2. Base styles (low specificity) */
body {
font-family: Arial, sans-serif;
line-height: 1.6;
color: #333;
}
h1, h2, h3 {
line-height: 1.2;
margin-bottom: 1rem;
}
/* 3. Component styles (medium specificity) */
.card {
background: white;
border: 1px solid #ddd;
border-radius: 8px;
padding: 1.5rem;
margin-bottom: 1rem;
}
.card-title {
font-size: 1.25rem;
margin-bottom: 0.5rem;
}
.card-text {
color: #666;
}
/* 4. Utility classes (higher specificity) */
.text-center {
text-align: center;
}
.text-primary {
color: #3498db;
}
.mb-0 {
margin-bottom: 0;
}
/* 5. State styles (highest specificity) */
.card:hover {
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
}
.card.active {
border-color: #3498db;
}
BEM Methodology
BEM (Block Element Modifier) controls specificity:
/* Block */
.card { }
/* Element */
.card__title { }
.card__text { }
/* Modifier */
.card--primary { }
.card__title--large { }
Specificity is always 10-20 — Prevents specificity wars.
Complete Example: Specificity in Action
/* Specificity: 1 */
p {
color: #333;
}
/* Specificity: 10 */
.intro {
color: #3498db;
}
/* Specificity: 100 */
#main-content {
color: #2ecc71;
}
/* Specificity: 110 */
#main-content .intro {
color: #e74c3c;
}
/* Specificity: 101 */
#main-content p {
color: #9b59b6;
}
<div id="main-content">
<p class="intro">This text is red (specificity 110)</p>
</div>
Debugging Specificity
Browser DevTools
Right-click element → Inspect → See which rules apply
Specificity Calculator
/* Use this to calculate */
/* Element: 1 */
/* Class: 10 */
/* ID: 100 */
/* Inline: 1000 */
Best Practices
- Keep specificity low — Easier to override
- Use classes over IDs — More reusable
- Avoid !important — Use specificity instead
- Follow CSS order — Base → Components → Utilities → States
- Use BEM naming — Consistent specificity
Common Mistakes
- Using !important everywhere — Creates specificity wars
- Overly specific selectors —
#main > div > ul > li > a - Not understanding inheritance — Some properties inherit, some don’t
- Ignoring source order — Later rules win when specificity is equal
- Mixing methodologies — Stick to one approach