Inheritance is the rule that some property values flow from a parent element to its children automatically. It is why setting a font on the body changes the font of everything inside it, and why not setting a colour anywhere on a page does not leave the text colour at an unspecified value.
Which properties are inherited?
Many text-related properties are, and most box properties are not. The list is worth learning by heart for the common ones, because it explains most surprises.
inherited not inherited
--------------------------- ---------------------------
color margin
font-family padding
font-size border
font-weight background
font-style width, height
line-height display
letter-spacing position
text-align z-index
text-indent overflow
text-transform flex properties
visibility box-sizing
cursor opacity (see note)
The pattern is clear: properties that describe text are inherited, and properties that describe boxes are not. That is not an accident of implementation — a child's padding should not be set by its parent's padding, but a child should look like it is in the same document as its parent.
How do you set a sensible default?
Because inherited properties cascade from the parent, the usual pattern is to set the text defaults on the root element and let everything else follow.
:root {
color: #1c1c1c;
font-family: system-ui, -apple-system, "Segoe UI", sans-serif;
font-size: 100%;
line-height: 1.5;
}
body {
background: #fff;
}
Setting these on :root rather than on body matters for a subtle reason: html is the ancestor of everything, including elements that are rendered outside the body, such as a popup's contents or the scrollbars. The :root selector matches the root element, which is html.
What do inherit, initial, unset and revert mean?
These four keywords let you change how a value is inherited, and each one means something slightly different.
.child {
color: inherit; /* take the parent's computed value, whatever it is */
color: initial; /* use the property's default value from the specification */
color: unset; /* inherit for inherited properties, initial for the rest */
color: revert; /* use whatever the user agent or a lower-priority origin says */
}
inherit is the one you will use most, and it is the answer to "I want this element to match its parent exactly, even for properties that are not inherited by default". A common use is a link inside a heading: links have their own colour by default, and color: inherit makes the link take the heading's colour instead.
unset is the clever one. It means "inherit if this property is inherited, otherwise reset it to the initial value" — which is almost always what you want when you are clearing a value you did not set yourself.
How do you stop a value being inherited?
Set the property explicitly on the child. An explicit value always beats an inherited one, whatever the specificity of the parent's rule.
.card {
color: #1c1c1c;
font-size: 1rem;
}
.card h3 {
color: #800d4d; /* explicit: does not inherit the card's colour */
font-size: 1.25rem;
}
Two properties need care. visibility is inherited, and a child that sets visibility: visible can become visible again inside a parent that is hidden — a detail that surprises people when they try to hide a wrapper. And opacity is not inherited: setting it on a parent makes the whole group translucent, because opacity applies to the rendered result of the group, not to each child.
Why does inheritance matter in practice?
Because it determines how much CSS you write. A stylesheet that sets the text properties once at the root and lets them flow down is far shorter and far more consistent than one that sets the font on every selector. It also gives you a predictable place to change things: if the base font is set on the root, one line changes it everywhere.
/* the whole site's typography in one place */
:root {
--font-body: system-ui, sans-serif;
--font-heading: Georgia, "Times New Roman", serif;
--text-size: 1rem;
--text-muted: #5c5c5c;
}
body { font-family: var(--font-body); font-size: var(--text-size); }
h1, h2, h3 { font-family: var(--font-heading); }
The custom properties in that example are themselves inherited, which is why a variable defined on the root is available everywhere — and why redefining a variable on a subtree changes only that subtree. That behaviour is the foundation of theming, and it works precisely because inheritance is doing what it always does.
Which properties inherit by default?
Inheritance is not all-or-nothing. Most properties are set on every element and never travel down the tree, but a specific list of them does pass from a parent to its children, and knowing that list explains a lot of surprising behaviour.
The inheritable ones are mostly the text properties: color, font-family, font-size, font-style, font-weight, line-height, letter-spacing, text-align, text-indent, text-transform, visibility, white-space, word-spacing, list-style-type and list-style-position, plus cursor and direction.
<div class="panel">
<!-- inherits color and font-size from .panel -->
<p>This text takes the panel's colour.</p>
<!-- does not inherit: padding and border are never inherited -->
<span class="badge">New</span>
</div>.panel {
color: #33475b;
font-size: 1.05rem;
}
.badge {
/* padding and border are not inherited, so they must be set here */
padding: 0.2rem 0.5rem;
border: 1px solid #b9c6d2;
border-radius: 999px;
}That is why a single color on the body styles most of a page, while a single padding on the body styles nothing at all.
You can override the behaviour for any property with the four global keywords. inherit forces the parent value on a child, which is useful for opting a specific element back into inheritance. initial sets the property to its default value. unset means inherit if the property inherits and use the initial value otherwise, which is what you usually want when resetting a property you did not create. And revert rolls the declaration back to whatever the previous cascade level said.
Quick reference
- Text properties inherit; box properties do not.
- Set the inherited defaults on
:rootso they reach every element. inheritforces the parent value,unsetmeans inherit-or-reset,initialresets,revertdefers to a lower origin.- An explicit value on a child always beats an inherited one.
visibilityis inherited and can be undone by a child;opacityis not inherited at all.- Custom properties are inherited, which is what makes theming possible.
Try it yourself: set a font and a colour on the root element and watch both flow into a deeply nested list. Then add a padding rule on a parent and confirm the child does not inherit it. Finally, put color: inherit on a link inside a coloured heading and see the link match the heading exactly.