Cascade is a fundamental concept of CSS. After all, it's in the name itself, the first C of CSS - Cascading Style Sheets - it must be an important thing.
What does it mean?
Cascade is the process, or algorithm, that determines the properties applied to each element on the page. Trying to converge from a list of CSS rules that are defined in various places.
It does so taking in consideration:
- Specificity
- Importance
- Inheritance
- Order in the file
It also takes care of resolving conflicts.
Two or more competing CSS rules for the same property applied to the same element need to be elaborated according to the CSS spec, to determine which one needs to be applied.
Even if you just have one CSS file loaded by your page, there is other CSS that is going to be part of the process. We have the browser (user agent) CSS. Browsers come with a default set of rules, all different between browsers.
Then your CSS come into play.
Then the browser applies any user stylesheet, which might also be applied by browser extensions.
All those rules come into play while rendering the page.
We'll now see the concepts of specificity and inheritance.
Specificity
Specificity is what determines which CSS rule is applied when multiple rules target the same element with conflicting properties.
Specificity Hierarchy
- Inline styles - Styles applied directly to HTML elements
- ID selectors - Styles applied to elements with specific IDs
- Class selectors - Styles applied to elements with specific classes
- Element selectors - Styles applied to specific HTML elements
Specificity Examples
/* Inline style - Highest specificity */
<div style="color: red;">Text</div>
/* ID selector - High specificity */
#my-id {
color: blue;
}
/* Class selector - Medium specificity */
.my-class {
color: green;
}
/* Element selector - Low specificity */
div {
color: purple;
}
Inheritance
Inheritance is a mechanism where properties on parent elements are inherited by their child elements. Not all CSS properties are inherited, but many are.
Inherited Properties
Commonly inherited properties:
- color
- font-family
- font-size
- font-weight
- line-height
- text-align
- visibility
Non-Inherited Properties
Commonly non-inherited properties:
- background-color
- border
- margin
- padding
- width
- height
- position
Inheritance Example
/* Parent element */
.parent {
color: blue;
font-size: 18px;
background-color: lightgray;
}
/* Child element inherits color and font-size */
.child {
/* color: blue (inherited) */
/* font-size: 18px (inherited) */
background-color: white; /* Not inherited */
}
Importance
The !important rule is used to give a CSS property more importance than normal rules. When !important is used, that CSS rule will override any other CSS rule for that specific property.
Using !important
/* Normal rule */
p {
color: blue;
}
/* More specific rule */
.container p {
color: green;
}
/* !important rule - overrides everything */
p {
color: red !important;
}
When to Use !important
Appropriate uses:
- Utility classes that must always win
- Overriding inline styles
- Overriding third-party CSS
- Accessibility overrides
Avoid using !important for:
- General styling (use specificity instead)
- Debugging (it can hide the real problem)
- Lazy fixes (refactor your CSS instead)
Order of Rules
When specificity is the same, the order of CSS rules determines which one is applied. The last rule in the source order wins.
Source Order Example
/* First rule - lower specificity */
p {
color: blue;
}
/* Second rule - same specificity, wins */
p {
color: red;
}
/* Result: text will be red */
CSS Loading Order
<!-- First stylesheet -->
<link rel="stylesheet" href="styles1.css">
<!-- Second stylesheet - overrides first -->
<link rel="stylesheet" href="styles2.css">
Complete Cascade Example
HTML Structure
<div id="container" class="wrapper">
<p class="text">This is some text</p>
</div>
CSS Rules
/* 1. Browser default styles */
/* 2. User agent styles */
/* 3. Author styles (our CSS) */
/* Element selector - specificity: 0,0,0,1 */
p {
color: black;
font-size: 16px;
}
/* Class selector - specificity: 0,0,0,1 */
.text {
color: blue;
font-size: 18px;
}
/* ID selector - specificity: 0,0,1,0 */
#container {
color: green;
}
/* Multiple classes - specificity: 0,0,0,2 */
.wrapper.text {
color: purple;
}
/* ID + class - specificity: 0,0,1,1 */
#container .text {
color: orange;
}
/* 4. User styles (browser extensions) */
/* 5. Inline styles - highest specificity */
<div style="color: red;"></div>
Result Analysis
Which color will be applied?
- If no inline style:
#container .textwins (orange) - If inline style is present: inline style wins (red)
- If
!importantis used: it overrides everything
Best Practices
โ Do:
- Use specificity instead of
!importantwhen possible - Keep CSS specificity low and predictable
- Use class selectors for styling
- Use ID selectors sparingly
- Avoid inline styles in HTML
- Organize CSS files logically
- Use inheritance to reduce code duplication
โ Don't:
- Overuse
!important - Create overly specific selectors
- Rely on source order for conflicts
- Use inline styles for regular styling
- Ignore specificity in complex projects
- Assume inheritance works for all properties
Summary
The CSS cascade is a fundamental concept that determines which styles are applied to elements. Understanding specificity, inheritance, importance, and source order is crucial for writing maintainable CSS.
Key Takeaways:
- Inline styles have highest specificity
- ID selectors beat class selectors
- Class selectors beat element selectors
!importantoverrides everything (use sparingly)- Some properties are inherited, others are not
- When specificity is equal, source order matters
- Browser defaults -> User styles -> Author styles -> Inline styles
- Use low specificity and inheritance for maintainable CSS
- Document cascade rules for team consistency
- Consider modern cascade features like @layer
- Test cascade behavior across browsers and devices
- Master the cascade for predictable, maintainable styles
Master the cascade to write better, more predictable CSS!