Cascade, Inheritance, and Specificity
Introduction
Most CSS confusion comes from one question: why did this rule win? The answer is usually the cascade, inheritance, and specificity working together. This chapter gives you a practical model for resolving style conflicts without random trial-and-error edits.
Prerequisites
- Basic CSS syntax and selectors
- Familiarity with class and ID selectors
- A browser with DevTools
The Cascade: How CSS Chooses a Winner
When multiple declarations target the same property on the same element, CSS resolves conflicts using the cascade.
At a practical level, think in this order:
- Importance (
!important) - Specificity
- Source order (later rules win when specificity ties)
Example:
.title {
color: #334155;
}
.title {
color: #2563eb;
}The second rule wins because it appears later.
Inheritance: Styles Passed from Parent to Child
Some properties naturally inherit from parent elements, so children receive values automatically.
Common inherited properties:
colorfont-familyfont-size(unless overridden)line-height
Example:
body {
color: #1e293b;
font-family: system-ui, sans-serif;
}Most text elements inside body inherit these values.
Common non-inherited properties:
marginpaddingborderwidth/heightbackground
If a property does not inherit, you must apply it directly where needed.
Specificity: Selector Strength
Specificity decides which selector is stronger when multiple rules target the same property.
Rough strength ranking:
- Inline style (strong)
- ID selector (
#id) - Class / attribute / pseudo-class (
.class,[type="text"],:hover) - Element / pseudo-element (
h1,::before)
Simple examples:
p {
color: #0f172a;
}
.note {
color: #2563eb;
}For <p class="note">, .note wins because class specificity is higher than element specificity.
Specificity in Action
HTML:
<p id="intro" class="note">Welcome</p>CSS:
p {
color: #0f172a;
}
.note {
color: #2563eb;
}
#intro {
color: #dc2626;
}#intro wins because ID specificity is higher.
Source Order Still Matters
If specificity is equal, later declaration wins:
.button {
background: #2563eb;
}
.button {
background: #1d4ed8;
}Second rule wins due to source order.
This is why stylesheet import order and rule placement matter in larger projects.
What !important Does
!important is a CSS force flag for priority. Its job is to push one declaration to the highest importance level. Normally, CSS decides winners with specificity and source order; once a declaration has !important, it usually beats conflicting normal rules (rules without !important).
What the Syntax Looks Like
The format is:
property: value !important;Note: !important comes after the value, and the semicolon still goes at the end.
.button {
background: #2563eb !important;
}This means: keep .button’s background as #2563eb when possible—even a later, higher-specificity normal rule often cannot override it.
A Side-by-Side Example
Without !important, the ID selector wins:
<button id="submit" class="button">Submit</button>.button {
background: #2563eb;
}
#submit {
background: #dc2626;
}Result: the button background is red, because #submit has higher specificity than .button.
If you add !important to the class rule:
.button {
background: #2563eb !important;
}
#submit {
background: #dc2626;
}Result: the button background is blue. .button has lower specificity, but with !important it beats the normal #submit rule.
Use Cases and Risks
Use cases:
- utility override layers
- controlled exceptions in design systems
Risks:
- hard-to-override rules
- cascading “importance wars”
- reduced maintainability
Warning
Use !important Sparingly
If you frequently need !important, the real issue is usually selector architecture or file order.
Practical Conflict Debugging
When a style does not apply:
- Inspect element in DevTools
- Check if selector matches
- Find crossed-out declaration
- Compare winning rule specificity
- Check load order and file order
- Verify inherited vs non-inherited property behavior
This method solves most “CSS not working” cases quickly.
Resetting and Explicit Keywords
Useful keywords when dealing with cascade and inheritance:
inherit: force element to inherit parent valueinitial: reset to CSS initial valueunset: acts like inherit for inherited properties, initial for othersrevert: reverts to earlier cascade origin
Example:
.card a {
color: inherit;
}This makes links inside .card use the card text color unless overridden.
Architecture Tips to Avoid Specificity Problems
- Prefer class selectors over IDs for styling
- Keep selectors shallow
- Organize styles in predictable layers (base, components, utilities)
- Avoid over-nesting in preprocessors
- Use naming conventions consistently
Good architecture reduces conflict before debugging is needed.
Tip
Winning by Design
The best CSS strategy is not “stronger selectors,” but clearer structure and predictable layering.
Mini Exercise
Create this HTML:
<article class="post">
<h2 id="post-title" class="title">Cascade Demo</h2>
<p class="text">Learning specificity.</p>
</article>Then:
- Add conflicting color rules for
h2,.title, and#post-title - Predict winner before checking browser
- Reorder rules and observe source-order changes
- Add one
!importantand observe impact - Remove
!importantand solve using better selector strategy
FAQ
Which is more important: specificity or source order?
Specificity first. Source order decides only when specificity ties.
Why does text color inherit but margin does not?
Because inheritance is property-specific by CSS design. Text-related properties often inherit; box-model properties usually do not.
Is using IDs for styling always wrong?
Not always, but heavy ID-based styling increases specificity pressure and makes overrides harder in larger codebases.
Should I ban !important completely?
You can allow it in limited, intentional cases, but it should be rare and justified.
How do I get better at specificity debugging?
Use DevTools daily and always ask: selector match, specificity strength, and source order. With repetition, conflict resolution becomes fast.