CSS
Specificity and Cascade
Master how CSS decides which styles win when multiple rules target the same element
When multiple CSS rules try to style the same element, which one wins? CSS has built-in rules calledspecificity and the cascade that determine this. Think of it like a scoring system — higher scores override lower ones.
Understanding these rules prevents styling headaches and makes your code predictable. The WanderLust team needs this knowledge to manage their growing stylesheet effectively.
The Cascade Explained
The cascade means CSS rules "flow down" like a waterfall. When browsers find conflicting styles, they use this order to decide winners:Basic Cascade Example
/* WanderLust destination cards — later rules override earlier ones */
.destination-card {
background: #f8fafc; /* This runs first */
}
.destination-card {
background: #0ea5e9; /* This wins - same specificity, appears later */
}What just happened?
Both rules have identical specificity (one class each), so the second rule wins because it appears later in the code. The cards display with blue backgrounds instead of gray. Try this: move the first rule below the second and watch the colors flip.
Specificity Scoring
Specificity works like a point system. Each selector type has a different value:1000 points
style="color: red"
100 points each
#header, #main
10 points each
.button, [href]
1 point each
h1, p, div
Calculating Specificity
/* WanderLust navigation — different specificity scores */
/* Score: 1 point (1 element) */
nav {
color: #64748b;
}
/* Score: 11 points (1 element + 1 class) */
nav.main-nav {
color: #0f172a;
}
/* Score: 101 points (1 ID) */
#navigation {
color: #0ea5e9;
}What just happened?
Each navigation gets a different color based on specificity scores. The ID selector (#navigation) with 101 points beats the class selector (11 points), which beats the element selector (1 point). Even if you moved the rules around, the scores would still determine the winners.
Complex Specificity Examples
Real stylesheets combine multiple selector types. Calculate the total points:/* WanderLust booking form — complex selectors */
/* Score: 1 point (1 element) */
button {
background: #64748b;
}
/* Score: 21 points (2 classes + 1 element) */
.booking-form .submit-button {
background: #15803d;
}
/* Score: 112 points (1 ID + 1 class + 1 element) */
#contact-form .submit-button {
background: #0ea5e9;
}Attribute and Pseudo-Class Specificity
Attribute selectors and pseudo-classes (like:hover) each count as 10 points — same as regular classes:
/* WanderLust destination links — pseudo-classes count as 10 points */
/* Score: 11 points (1 element + 1 pseudo-class) */
a:hover {
color: #f97316;
}
/* Score: 21 points (1 class + 1 element + 1 pseudo-class) */
.destination-link:hover {
color: #0ea5e9;
text-decoration: underline;
}What just happened?
Hover over both links to see different colors. The .destination-link:hover selector (21 points) beats the a:hover selector (11 points), so destination links get blue hover colors while basic links get orange. Pseudo-classes add 10 points to specificity calculations.
The !important Declaration
The!important declaration is like a nuclear option — it overrides almost everything. Use it sparingly because it breaks the natural cascade:
/* WanderLust emergency override — !important beats higher specificity */
/* Score: 101 points (1 ID) */
#header {
background: #0ea5e9;
}
/* Score: 1 point + !important (wins anyway) */
header {
background: #dc2626 !important;
}Use !important Carefully
The !important declaration makes styles nearly impossible to override later. Only use it for utility classes or when fixing third-party CSS conflicts. Most styling problems have better solutions through proper specificity management.
Inheritance and the Cascade
Some CSS propertiesinherit from parent elements automatically. Text properties like color and font-family flow down the HTML tree:
/* WanderLust content section — inheritance in action */
.content-section {
color: #0f172a; /* Children inherit this color */
font-family: system-ui, sans-serif; /* Children inherit this font */
}
.special-text {
font-style: italic; /* Adds italic, keeps inherited color and font */
}.content-section automatically get the dark color and system font. The .special-text paragraph adds italic while keeping the inherited styles.
Controlling Inheritance
You can control inheritance with special keywords:/* WanderLust navigation — inheritance control keywords */
.main-navigation {
color: #0ea5e9;
font-size: 18px;
}
.nav-button {
color: inherit; /* Use parent's color (#0ea5e9) */
font-size: initial; /* Use browser default, ignore parent */
border: none;
padding: 8px 16px;
}What just happened?
The button uses color: inherit to get the navigation's blue color, but font-size: initial resets to the browser's default size instead of inheriting 18px. These keywords give you precise control over what styles inherit and what don't.
Best Practices for Managing Specificity
Keep your CSS maintainable by following these specificity guidelines:| Strategy | Example | Why It Works |
|---|---|---|
| Use single classes | .button |
Low specificity, easy to override |
| Avoid deep nesting | .card .button vs .nav .header .menu .item .button |
Prevents specificity wars |
| Reserve IDs for JavaScript | id="contact-form" |
Keeps styling specificity lower |
| Use modifier classes | .button.primary |
Slight specificity increase for variants |
The Specificity Sweet Spot
Aim for consistent, moderate specificity levels throughout your stylesheet. This makes it easier to override styles when needed without reaching for !important or writing increasingly complex selectors.
Quiz
1. What's the specificity score of this WanderLust selector: #booking-form .submit-button
2. If WanderLust has both a { color: red; } and .destination-link { color: blue; } rules, what happens to a link with class="destination-link"?
3. When should the WanderLust team use !important in their CSS?
Up Next: Colors and Units
Master CSS color formats, measurement units, and responsive sizing techniques for professional designs.