CSS fundamentals · 4 / 8
lesson 4

Inheritance and the keyword cascade

Some properties trickle down to children, some don't — and four keywords let you steer that flow precisely.

~ 15 min read·lesson 4 of 8
0 / 8

You set color: navy on the <body> and every paragraph, list item, and link description on the page comes out navy — even though you never wrote a rule for any of those individually. You set border: 1px solid red on the same <body> and… only the body itself gets the border. Same parent, same property syntax, completely different behaviour. The difference is inheritance, and once you know which properties inherit and which do not, the page stops feeling magical and starts feeling like a logical tree.

What inheritance is, and what it isn't

Every HTML page is a tree of nested elements: <html> contains <body>, which contains a <main>, which contains a <p>, which contains a <a>. Inheritance is the rule that, for some CSS properties, the value on a parent flows down to children that have no value of their own.

Think of it like a dress code at an event. The host announces "tonight, everyone wears black". Guests with no opinion of their own follow the announcement; guests who packed a red jacket and put it on override the dress code for themselves. Their plus-one — who again has no opinion — follows the host's rule, not the guest's red jacket. The default flows down through everyone who hasn't made their own choice.

styles.css
body {
color: #2d2418;
font-family: system-ui;
}

Set color and font-family on the body and every text-bearing element inside the body inherits both. You did not need to write a rule for <p>, <li>, <a>, or <span> separately — they all picked up the same colour and font from the body. That is inheritance doing the boring work for you.

Inheritance is not the same as the cascade from lesson 3. The cascade picks a winner when two rules compete on one element. Inheritance is what happens when no rule matches at all — the browser asks the parent. The two systems work together: cascade decides what value an element ends up with when rules apply, and inheritance fills in values for elements that no rule touched.

Which properties inherit

You cannot make every property inherit, no matter how convenient that would feel. The CSS spec marks each property as either "inherited" or "not inherited", and the split is not random — it follows what is useful to inherit.

Properties that inherit by default are the typographic ones: text colour, font, line height, letter spacing, text alignment, list style, visibility. These are properties where, almost always, you want a child to look like its parent unless told otherwise. Setting font-family once on the body would be miserable if every child needed to repeat the rule.

Properties that do not inherit by default are the box-shape ones: padding, margin, border, width, height, background, position. These are properties where inheriting would be a disaster. Imagine setting border: 1px solid red on the body and every paragraph, link, and span getting its own one-pixel border. The page would look like a notebook.

You will not memorize the full list, and you do not need to. The shorthand for "is this property inherited?" is: if it is about how the text reads, probably yes. If it is about the box around the text, probably no. When in doubt, the MDN page for any property tells you in one line whether it inherits.

bodyh1pa color: navy → inherits, every box gets it border: 1px solid → does not, only body gets itbody only
Typographic properties trickle down through the tree. Box properties stop at the element they are set on.
check your understanding
You set body { font-family: 'Georgia'; padding: 32px; }. Which is true on a child <p>?

The four cascade keywords

CSS gives you four keywords that let you reach into the cascade and force a property to a specific source. They look small, but they solve real problems — especially when you want to "undo" a style without knowing exactly what it was set to. Each keyword is a value you can use anywhere a value is allowed.

inherit forces the element to take its parent's computed value, even for properties that don't normally inherit. If you want every link inside a .warning block to share the warning's text colour even though links override color by default, you can write a { color: inherit; } and the link picks up whatever colour its parent ended up with.

styles.css
.warning { color: #b8400a; }
.warning a { color: inherit; }

The first rule paints the warning block in a deep orange. The second rule says links inside the warning take the parent's colour — which is #b8400a — instead of the browser's default link colour. Without inherit, the link would default to blue and look wrong.

initial forces the property back to its CSS-spec default, ignoring everything else. Note: this is the spec default, not the browser's user-agent stylesheet. The spec default for color is black; for display it is inline. So display: initial on a <div> makes it inline — usually not what you want. initial is a sharper tool than it looks.

unset is the everyday one. It says "act as if no rule had touched this property" — which means inherit if the property normally inherits, otherwise fall back to the spec default. It is a clean reset that respects the property's nature.

revert is the gentlest of the four. It says "go back to whatever the user-agent stylesheet (or any user style) had for this property." So display: revert on a <div> gives you block, because that is the browser default — which is almost certainly what you actually wanted.

reset.css
/* "Make this button look like a plain inline element again,
  as if the browser default were back in charge." */
button.unstyled {
all: revert;
cursor: pointer;
}

The rule resets every property on .unstyled buttons back to the browser default in one line, then adds the cursor change you actually want. That all keyword is coming up next.

The thing to take away from the four keywords is the difference between initial, unset, and revert. initial jumps to the spec default. unset lets the property behave naturally — inherit if it should, default if it should not. revert returns to the browser's default. Most of the time, revert is what you mean when you say "reset" out loud.

check your understanding
You wrote div.fancy a { color: gold }. You want one specific link inside .fancy to look like a normal link again. Which value does that cleanly?

The all property

The all property is a wildcard that targets every property at once. It only accepts the four cascade keywords (inherit, initial, unset, revert) plus a few newer additions — you cannot say all: 16px. Its job is to wipe an element back to a known state in one declaration.

reset.css
fieldset.bare {
all: revert;
}

That single line resets every property on .bare fieldsets back to the browser default — useful when you want to undo a heavy custom style and start fresh. Use it sparingly: it really does mean every property, including ones you might forget about.

Tip

When a child is picking up a style from somewhere and you cannot find the rule, devtools' Computed panel shows the final value for every property on the element, with a link back to the source. If the source says "inherited from <body>", you have your answer in one click.

check your understanding
A page-wide rule sets * { margin: 0 }. You want the default margins back on a single article body. Which is the simplest fix?
check your understanding
Which best describes the difference between cascade and inheritance?
← prevnext lesson →
KeepLearningcertificate
for completing
CSS fundamentals
0 of 8 read