Skip to main content
CodeOath
← All posts

HTML & CSS82 min total · 18 parts

CSS Fundamentals: The Box Model, Specificity, Positioning, and Layout

Part 6 of 18 · ~2 min

The Cascade, Inheritance, and !important

Three different people end up touching this card's CSS over its lifetime: whoever wrote the site-wide reset, whoever built the card component itself, and whoever on the marketing team needs a one-off style for a holiday sale banner. When their rules disagree, CSS resolves the conflict through three mechanisms, checked in this order:

  1. Importance — anything marked !important outranks a normal declaration, and it stops mattering afterward how specific either selector was.
  2. Specificity — when neither declaration is !important, whichever selector scores higher wins; the next chapter is the full scoring system.
  3. Source order — the last tiebreaker: if two declarations are equally important and equally specific, whichever one was parsed last — further down the same file, or in a stylesheet linked in afterward — is the one that actually takes effect.
.price { color: #1a1a1a; }
.price { color: #b1500f; } /* identical specificity, comes later — this one wins */

Inheritance runs on entirely separate rules from the three above, and it's worth keeping the two ideas apart in your head. Typography-adjacent properties — think font-family, font-size, line-height, color, text-align — flow down from a parent into every descendant automatically, unless a more specific rule intercepts them first. Box-shaped properties don't do this at all: border, margin, padding, background, and width stop dead at whatever element declared them. Set font-family once, on <body>, and the card's title, price, and button text all pick it up without a single extra line; set border on .card and none of its children know that border exists.

Three keywords let you push a property against its default inheritance behavior, either direction:

.card .price {
  color: inherit; /* pull the parent's resolved value, even though color already inherits by default */
}
.card {
  border: initial; /* wipe it back to the spec's own default, bypassing the cascade altogether */
}
.card__badge {
  all: unset; /* every inheriting property here acts like inherit; every non-inheriting one acts like initial */
}

Now, the marketing team's sale banner. It's a one-off, it has to ship before the holiday sale starts in an hour, and the fastest fix on hand is:

.promo-banner .price { color: #c2185b !important; }

That works, and that's exactly the problem. !important sits outside the specificity system entirely rather than scoring especially high within it, so whoever eventually has to undo this rule is stuck matching it with an !important of their own, escalating the same standoff one level further. Only a more specific !important declaration beats an existing one — or a later one, if the two tie on specificity too. Save it for CSS you genuinely don't own — a third-party widget's stylesheet, something pulled in from a CDN — and keep it out of code your own team maintains. Every !important written into your own stylesheet is a decision the next person touching that file has to work around, not with.