Lesson · Beginner
Understand the cascade and inheritance
Predict which CSS declaration wins, trace inherited values, and structure layers so fixes do not depend on selector escalation.
- Published
- Last checked
The problem the cascade solves
Several CSS declarations can assign the same property to the same element. A browser needs a deterministic way to choose one. The cascade is that process. It filters declarations that do not apply, compares origin and importance, orders cascade layers, compares specificity where necessary, and finally uses proximity or source order to resolve the remaining tie.
That sequence matters because “the most specific selector wins” is incomplete. A declaration in a stronger origin or layer can win before specificity is ever compared. An inline style, an important user preference, an unlayered author rule, and a low-specificity rule in a later layer each belong to different parts of the decision.
Start with one observable conflict
<p class="notice">Registration closes Friday.</p>
@layer reset, base, components;
@layer base {
p {
color: #334155;
}
}
@layer components {
.notice {
color: #8b1e3f;
}
}
Both declarations are normal author styles. The components layer comes later in the declared layer order, so its rule wins. The class also has greater specificity, but the layer decision occurs first. If the layer order changed, specificity would not rescue a rule in the weaker layer.
Read the cascade in the right order
First ask whether the selector and condition match. A rule inside a false media query or unsupported feature condition is irrelevant. Next identify origin and importance: browser defaults, user styles, author styles, animation and transition values, and important declarations have defined precedence.
Within an origin, inspect layers. Normal unlayered author rules outrank normal layered author rules, so adopt layers deliberately rather than wrapping only a few weak rules and expecting them to override legacy CSS. Then compare specificity among rules in the same relevant bucket. If those values tie, the later declaration normally wins.
Browser developer tools display matched and overridden declarations. Expand the computed property, find every candidate, and name the exact stage that removed each loser. This is faster and safer than adding another selector until the screen changes.
Inheritance is a separate step
After the cascade finds no declared value on an element, an inherited property may use the parent's computed value. Text color, font family, and line height commonly inherit. Margin, border, width, and most layout properties do not.
.article {
color: #17211b;
font-family: system-ui, sans-serif;
}
Paragraphs, links, and emphasis inside the article can inherit those text values. A link may also receive a color from the browser or another rule, which means the cascade supplies a value and inheritance is no longer used for that property.
The keywords are precise tools. inherit requests the parent's computed value.
initial requests the property's defined initial value. unset chooses
inheritance for inherited properties and initial behavior otherwise. revert
and revert-layer step back through cascade history. They are not generic
synonyms for “remove this style.”
Design a layer boundary
A small site can use a stable order such as reset, base, components, and utilities. Put element defaults in base, reusable interface rules in components, and narrowly scoped helpers in utilities. Declare the order once near the top. Do not create a layer for every file or component; the point is to express a few ownership boundaries that a maintainer can explain.
Third-party CSS can sit in an early layer so local components override it without long selectors. Important declarations reverse layer precedence within their importance group, which protects earlier important rules. Avoid relying on that reversal casually. Important rules should be rare and have an explicit purpose such as respecting a user-facing utility or safety state.
Accessibility consequences
Cascade mistakes can erase focus indicators, validation state, reduced-motion overrides, forced-color behavior, or readable contrast. A component rule that wins visually on the default theme may lose to a later hover utility or inherit an unreadable color on a different surface.
Test interactive states in the computed panel. Confirm focus styling wins when the element is also hovered, active, invalid, disabled, or inside a theme. User styles and forced colors may override author decisions by design. Do not fight those origins merely to preserve brand presentation.
Common failure patterns
- Selector escalation. Each fix adds another ancestor or ID. Move ownership into a clear layer and reduce the competing rule.
- Unexplained
!important. The declaration wins but future states require more important rules. Reserve it for a documented boundary. - Accidental inheritance. A control inherits a color that loses contrast on its own background. Declare the component pair explicitly.
- Global reset damage. A universal rule removes outlines, list markers, or form behavior. Reset only what the design replaces safely.
- Media-query tie. Two conditions are true and source order decides a result nobody expected. Keep responsive changes near their component or layer.
Verify and practice
Choose one element with a crossed-out declaration in developer tools. Record the winning and losing origin, importance, layer, specificity, and order. Change only the stage responsible for the defect. Then test light and dark themes, focus, invalid state, reduced motion, forced colors, 200% zoom, and the narrow layout.
For practice, remove the class from the notice example and predict which values inherit. Add a utility layer and observe its normal precedence. Then add an important declaration in two layers and explain why the earlier important layer wins. If the result surprises you, keep the example small until every step is predictable before returning to a full stylesheet.
Free template + launch checklist
Build a page you can check before launch
Start with one reviewed semantic HTML page, then work through the one-page checklist against your published URL.