CSS Lesson 5 – Specificity and Cascade | Dataplexa
Lesson 5

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 called specificity 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:
1
Source Order
2
Specificity
3
Importance
4
Origin (Browser vs Author vs User)
Most of the time, specificity determines the winner. Source order acts as the tiebreaker when specificity scores match.

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 */
}
localhost/index.html

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:
Inline Styles
1000 points
style="color: red"
IDs
100 points each
#header, #main
Classes & Attributes
10 points each
.button, [href]
Elements
1 point each
h1, p, div
The browser adds up points for each selector. Higher totals win. If totals match, source order decides.

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; 
}
localhost/index.html

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; 
}
localhost/index.html
The ID + class combination scores highest at 112 points, making the contact form button blue. The two-class selector scores 21 points for green. The basic button stays gray at 1 point.

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;
}
localhost/index.html

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; 
}
localhost/index.html

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 properties inherit 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 */
}
localhost/index.html
The heading and paragraphs inside .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;
}
localhost/index.html

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.

Understanding specificity and the cascade transforms you from a CSS copier into a CSS master. You'll predict which styles apply, resolve conflicts quickly, and write more maintainable code. The WanderLust team can now confidently manage their growing stylesheet, knowing exactly why certain styles win and how to adjust them when needed. These fundamentals prevent the frustrating "why won't this CSS work?" moments that plague many developers.

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.