Mastering the Priority of CSS Styles
CSS Cascading and Specificity are the foundation of how browsers decide which styles to apply. In this article, we’ll explore how multiple CSS rules interact and which one takes precedence — from classic specificity formulas to modern @layer
rules.
🤔 Let’s Start with a Simple Example
When multiple CSS classes are applied to one element:
<div class="blue red green">What color is this text?</div>
.blue { color: blue; }
.red { color: red; }
.green { color: green; }
The final color is green.
This happens because CSS follows a cascading order, where later declarations take precedence when all else is equal.
🕰️ The Birth of Cascading
When CSS was first introduced in 1996, cascading was its key concept.
The design goals were:
- 🎯 Predictability: Developers can reason about the final result.
- ⚙️ Flexibility: Allow style overrides and inheritance.
- ⚖️ Balance: Respect both author and user styles.
This concept, created by Håkon Wium Lie, was meant to handle conflicts between multiple sources — author styles, user styles, and browser defaults.
⚖️ The System of Cascading Priorities
🎯 Specificity Formula
Specificity is represented as a four-part tuple:
(Inline, ID selectors, Class/Attribute/Pseudo-class, Element selectors)
Style Type | Weight | Example |
---|---|---|
Inline style | 1000 | style="color: red" |
ID selector | 100 | #header |
Class/attribute/pseudo-class | 10 | .active, [type=text] |
Element selector | 1 | div, p |
Universal selector | 0 | * |
🔍 Real Examples
/* Specificity: (0, 0, 1, 1) = 11 */
div.blue { color: blue; }
/* Specificity: (0, 1, 0, 0) = 100 */
#content { color: red; }
/* Specificity: (0, 0, 2, 1) = 21 */
div.blue.active { color: green; }
/* Inline style: (1, 0, 0, 0) = 1000 */
<div style="color: yellow;">
⚠️ Note: Ten class selectors will never outweigh a single ID selector.
📝 Overriding Rules at Equal Priority
When selectors share the same specificity, source order decides which one wins.
.blue { color: blue; }
.red { color: red; }
.green { color: green; }
HTML order doesn’t matter — only the CSS definition order does:
<div class="green blue red">Green</div>
<div class="red green blue">Green</div>
<div class="blue red green">Green</div>
🎨 Priority in Complex Scenarios
<!DOCTYPE html>
<html>
<head>
<style>
div.red { color: red; } /* 11 */
.blue.text { color: blue; } /* 20 */
#content { color: green; } /* 100 */
.yellow { color: yellow; } /* 10 (later defined) */
</style>
</head>
<body>
<div id="content" class="red blue text yellow">
What color is this?
</div>
</body>
</html>
✅ Result: Green — because the ID selector has the highest priority.
If the ID is removed, blue.text (20) wins over red (11).
⚡ The Power of !important
.blue { color: blue !important; }
.red { color: red; }
.green { color: green; }
!important
overrides all other declarations, even with lower specificity.
💡 Usage Tips
✅ Use for overriding library defaults or utility classes.
❌ Avoid in component-level styles — it leads to “priority wars.”
🛠️ Best Practices in CSS Architecture
A recommended CSS priority structure:
/* 1. Reset styles — lowest priority */
* { margin: 0; padding: 0; }
/* 2. Base elements */
h1, h2, h3 { font-family: Arial, sans-serif; }
/* 3. Layout classes */
.container { max-width: 1200px; }
/* 4. Components */
.button { padding: 8px 16px; }
/* 5. States */
.button.active { background: blue; }
/* 6. Utilities — highest */
.text-center { text-align: center !important; }
🎯 Avoiding Conflicts
- Use BEM naming:
.card__title--highlighted { color: red; }
Instead of deeply nested selectors:
.card .content .title.highlighted { color: red; }
- Modular CSS-in-JS:
const styles = {
title: { color: "red" },
subtitle: { color: "blue" },
};
- Custom properties for flexibility:
.theme-blue { --primary-color: blue; }
.button { color: var(--primary-color, gray); }
🆕 Modern CSS: Cascade Layers
CSS now includes the powerful @layer
feature:
@layer base, components, utilities;
@layer base {
h1 { color: black; }
}
@layer components {
.title { color: blue; }
}
@layer utilities {
.text-red { color: red; }
}
Cascade order: base < components < utilities
This gives fine-grained control and clarity for large projects.
🔮 Logical Properties and Modern Trends
As CSS evolves with globalization and layout flexibility, logical properties change how cascading behaves:
.text {
margin-inline-start: 20px;
margin-left: 10px;
}
In browsers supporting logical properties, margin-inline-start
takes precedence over margin-left
.
Top comments (0)