Skip to main content
Syllabus
On this page

Cascade, Inheritance & !important

Badar KhalilUpdated September 29, 2026 5 min read

Understanding the CSS Cascade

The CSS cascade is the algorithm that resolves conflicts when many declarations apply to the same property on the same element. The C in CSS stands for Cascading, and it is the most important concept to master. Our focus keyword is CSS cascade, and this lesson also covers highly searched topics: CSS inheritance, CSS !important explained, cascade layers (@layer), inherit vs initial vs unset vs revert, why is my CSS not applying, and CSS @scope proximity.

The Cascade Order: Who Wins?

When two declarations conflict, the browser walks through these criteria in order and stops at the first that produces a winner:

  1. Relevance: only declarations that match the element and are valid are considered.
  2. Origin and importance: transition declarations, then !important user-agent, user, author declarations (in reverse order), then normal author, user and user-agent declarations, then animation declarations.
  3. Context: Shadow DOM scoping rules (outer context wins for normal declarations, inner wins for important).
  4. Element-attached styles: inline style attributes beat selector rules of the same level.
  5. Layers: the order of @layer blocks decides. For normal rules, later layers win and unlayered styles beat all layers. For !important the order reverses.
  6. Specificity: the (ID, class, element) score you learned in the previous lesson.
  7. Scoping proximity: with @scope, the declaration whose scope root is closest wins.
  8. Order of appearance: the last declaration in source order wins.

The Three Origins

  • User-agent styles: the browser default stylesheet (blue links, bold headings, margins on body).
  • User styles: preferences set by the visitor, such as forced font size or high-contrast themes.
  • Author styles: your CSS. This is what you write.

Normal declarations: author beats user beats user-agent. For !important the order flips, so a user-agent important rule beats an author important rule. This protects accessibility settings.

Cascade Layers with @layer

Cascade layers are one of the biggest modern CSS additions. They let you define explicit priority groups so that specificity from a low layer can never beat a rule from a higher layer.

Code
@layer reset, base, components, utilities;

@layer reset { * { margin: 0; box-sizing: border-box; } }
@layer components { .btn { background: royalblue; } }
@layer utilities { .bg-red { background: crimson; } }

Layers declared later win. Unlayered CSS beats all layered CSS for normal declarations. Layers are the recommended way to tame third-party CSS such as frameworks: import them into a low layer and keep your own styles above.

Inheritance

CSS inheritance means some properties pass their computed value from parent to child automatically when no cascade value is applied to the child.

Inherited by default

  • Text related: color, font-family, font-size, font-weight, line-height, text-align, letter-spacing
  • visibility, cursor, list-style, direction
  • CSS custom properties (variables), which inherit by default

Not inherited by default

  • Box model: margin, padding, border, width, height
  • background, display, position, overflow, opacity, transform

This is sensible: if borders inherited, every nested element would get its own border.

Control Keywords: inherit, initial, unset, revert, revert-layer

KeywordBehavior
inheritTake the parent's computed value, even for non-inherited properties
initialUse the property's spec-defined initial value
unsetActs as inherit for inherited properties, otherwise initial
revertRoll back to the previous origin, usually the browser default
revert-layerRoll back to the previous cascade layer

The shorthand all: unset or all: revert resets every property of an element. It is handy for isolated components.

The !important Declaration

Adding !important to a declaration moves it to a higher-priority tier of the cascade. It even beats inline styles (unless the inline style is also important).

Code
.alert { color: red !important; }

Why !important is dangerous

  • It breaks the natural cascade and makes overrides difficult.
  • It leads to important wars, where each fix needs another !important and higher specificity.
  • It makes CSS hard to maintain and debug.

Legitimate uses

  • Utility classes such as .hidden { display: none !important; } that must always win.
  • Overriding inline styles injected by third-party scripts you cannot change.
  • Accessibility and user preference rules, for example forcing minimal motion inside @media (prefers-reduced-motion: reduce).
  • Print stylesheets in specific cases.

Better alternatives

  • Reorder rules or reduce specificity of the competing rule.
  • Use @layer to give your styles higher priority.
  • Use a slightly more specific selector, or :where() on the losing side.
  • Use CSS custom properties to change values rather than fighting selectors.

Debugging the Cascade

  1. Open DevTools and select the element.
  2. Look for struck-through declarations in the Styles panel.
  3. Check the Computed tab and expand a property to see the winning rule.
  4. Check if a layer, media query or inline style is involved.
  5. Check for typos or invalid values, since invalid declarations are ignored and the cascade falls back to the previous rule.

Best Practices

  • Structure CSS with layers: reset, base, layout, components, utilities.
  • Rely on inheritance for typography: set font-family and color on body and let everything inherit.
  • Use custom properties for theming because they inherit naturally.
  • Reserve !important for utilities and accessibility.
  • Keep selectors flat and predictable, so the cascade stays easy to reason about.

Summary

The cascade sorts declarations by origin, importance, layers, specificity and order. Inheritance passes some values down the tree, and keywords like inherit, unset and revert give you precise control. Use !important sparingly and prefer layers. Explore the live examples below.

Try it Yourself HTML
Output

Press Run to execute.

Try it Yourself HTML
Output

Press Run to execute.

Try it Yourself HTML
Output

Press Run to execute.

Try it Yourself HTML
Output

Press Run to execute.

Try it Yourself HTML
Output

Press Run to execute.

Exercise: Use Inheritance for TypographyHTML

Without adding rules to individual paragraphs or headings, make all text inside .article use the font Georgia and the color #334155 by setting properties on a single element. Then make the <h2> ignore the inherited color by using a cascade keyword so it returns to the browser default.

Try it Yourself HTML
Output

Press Run to execute.

Show expected output
Paragraphs are Georgia and slate-colored. The heading uses the default black color.

This is a self-check — compare your result with the expected output above.

Exercise: Replace !important with @layerHTML

The rule for .card-title uses !important to beat a framework rule. Remove !important and use @layer so that your rule still wins and the title is crimson.

Try it Yourself HTML
Output

Press Run to execute.

Show expected output
The card title is crimson without using !important.

This is a self-check — compare your result with the expected output above.

Quiz: Cascade, Inheritance and !important Quiz Pass 70%
Loading quiz…

Was this page helpful?