Inheritance and CSS-Wide Values

Understand which CSS properties inherit from parent to child by default, and precisely distinguish the CSS-wide keywords inherit, initial, unset, revert, and revert-layer.

Not every CSS property behaves the same way when you don't explicitly set it on an element. Some properties automatically pick up their parent's computed value (inheritance); others reset to a built-in default. On top of that, CSS gives you five special keywords to explicitly control this behavior on any property, for any element — and mixing them up is one of the most common sources of confusing bugs.

Which properties inherit by default

CSS properties fall into two groups by design: inherited properties and non-inherited properties. This isn't arbitrary — properties inherit when it makes sense for a whole subtree to share a value (text-related properties, mostly), and don't inherit when sharing the value would cause visual chaos (box-model and layout properties, mostly).

• Typically inherited: color, font-family, font-size, font-weight, font-style, line-height, letter-spacing, text-align, visibility, cursor, list-style. • Typically NOT inherited: margin, padding, border, width, height, background, display, position, box-shadow, flex/grid properties.

Why the split makes sense

Imagine if border inherited by default: setting a border on <body> would draw a border around every single element on the page, nested inside each other — clearly not useful. But it makes total sense for a <div> with font-family: 'Georgia' to have all its nested <p>, <span>, and <li> elements automatically use Georgia too, without repeating the declaration everywhere. That's exactly why text-related properties inherit and box-model properties don't.

The five CSS-wide keywords

Beyond default behavior, CSS gives every property five special values you can assign explicitly. These are easy to confuse because they sound similar but behave in precisely different ways.

• inherit — forces the property to take the computed value of its parent, even if the property normally does NOT inherit (e.g. forcing a child's border to match its parent's). • initial — resets the property to its specification-defined default value, ignoring both the parent and any stylesheet, as if no author CSS existed at all. • unset — acts like inherit if the property is naturally inherited, or like initial if it is naturally NOT inherited. It's the 'do what would happen if no CSS-wide keyword existed' value. • revert — resets the property to the value it would have from the browser's (or user's) default stylesheet, as if your author-level CSS didn't declare it — but unlike initial, this preserves default browser styling (e.g. revert on display for a <li> gives list-item, not initial's inline). • revert-layer — like revert, but rolls back only to the value established in the previous cascade layer, not all the way to the browser default. Relevant only once you're using cascade layers (@layer), a more advanced topic covered later.

initial vs. revert — the key distinction

This is the pair developers mix up most. initial always resets to the CSS specification's defined default for that property (for display, that's inline, for every element). revert resets to whatever the browser's built-in stylesheet says for that specific element (for display on a <li>, that's list-item; for a <div>, that's block). In short: initial ignores what kind of element it is; revert respects the browser's sensible per-element defaults.

Using the CSS-wide keywords

inherit and unset can make a non-inherited property behave like an inherited one for that element. initial rarely equals revert for layout properties — they differ per element type.

/* inherit: force a non-inherited property to take the parent's value */
.card {
  border: 2px solid black;
}
.card .icon {
  border: inherit;   /* icon now also gets a 2px solid black border */
}

/* initial: reset to the specification default, ignoring everything */
.reset-color {
  color: initial;    /* becomes the spec default for color: usually black */
}

/* unset: inherit if the property naturally inherits, else initial */
.unset-demo {
  color: unset;      /* behaves like inherit (color is an inherited property) */
  margin: unset;     /* behaves like initial (margin is NOT inherited) -> 0 */
}

/* revert: roll back to the browser's default stylesheet for this element */
li {
  display: revert;   /* -> list-item, the browser default for <li>, not 'inline' */
}

Code Examples

This is why setting base typography once on body (or html) is standard practice — it cascades down through inheritance without needing repeated rules.

unset only differs from initial when the property is naturally inherited — otherwise they behave identically.

This pair is the classic proof of the difference: unset respects whether the property inherits; initial never does.

body {
  font-family: 'Georgia', serif;
  color: #222;
}

/* No CSS is written for <p>, <li>, or <span> —
   they automatically inherit font-family and color from body. */
.parent {
  padding: 40px;
}

.child-a { padding: initial; }  /* padding becomes 0 (spec default) */
.child-b { padding: unset; }    /* padding also becomes 0, because padding doesn't inherit */

/* For padding, initial and unset give the SAME result,
   because padding is a non-inherited property. */
.parent {
  color: crimson;
}

.child-a { color: initial; }   /* becomes the spec default, roughly black — ignores parent */
.child-b { color: unset; }     /* becomes crimson — inherits from parent, since color inherits */

/* Here initial and unset give DIFFERENT results,
   because color is an inherited property. */

How unset decides its behavior

unset is not a fixed value — its effect depends entirely on the property it's applied to.

property set to: unset
                    |
        Is this property naturally inherited?
            /                          \
         YES                            NO
           |                             |
   acts like `inherit`           acts like `initial`
  (take parent's value)      (take spec default value)

Important Rules

Text-related properties (color, font-*, line-height, text-align) inherit by default; box-model properties (margin, padding, border, width) do not.

inherit always pulls the parent's computed value, even for properties that don't normally inherit.

initial always resets to the CSS specification's default — it never looks at the parent or the browser stylesheet.

unset = inherit for naturally-inherited properties, initial for everything else.

revert resets to the browser's (or user's) default stylesheet value for that specific element type, preserving sensible per-element defaults that initial would erase.

Where these keywords actually get used

In practice, inherit is the most commonly used of the five — for example, forcing a <button>'s font-family to inherit from the page instead of the browser's default UI font. initial and unset show up in CSS resets and utility classes. revert is increasingly used when working with third-party or legacy CSS you want to 'undo' for one component, restoring sensible browser defaults without a full page reset.

li { display: initial; } /* trying to 'reset' a list item */ li { display: revert; } /* or simply don't override display at all */ display: initial resolves to inline (the spec default for the property), which breaks list markers and item layout. display: revert correctly restores list-item, the browser's actual default for <li>.

/* Assuming unset always means 'remove my styling entirely' */ .text { color: unset; border: unset; }

/* Know that unset's effect differs per property */ .text { color: unset; /* -> inherits from parent, since color inherits */ border: unset; /* -> resets to none, since border doesn't inherit */ }

Assuming unset behaves identically across all properties leads to surprises — always check whether the specific property you're resetting is inherited or not.

[Identify the Error] A developer wants a <span> to visually 'forget' any author CSS and fall back to plain browser defaults for that element type, so they wrote span { all: initial; }. For most inline text properties this works, but they're confused why it doesn't restore browser-specific quirks the way they expected on other elements. What's the more accurate keyword for 'reset to what the browser's own stylesheet says for this element'? A. unset — because it removes all custom styling B. revert — because it rolls back to the browser/user-agent stylesheet's value for that specific element, not the CSS specification's generic default C. inherit — because it takes the value from the parent element D. initial is already correct; there is no functional difference from revert

B. revert — because it rolls back to the browser/user-agent stylesheet's value for that specific element, not the CSS specification's generic default — initial resets to the CSS specification's default value for the property in general (ignoring what element it is), while revert resets to the browser's actual default stylesheet value for that specific element — which is what 'restore browser default appearance' really means. For many properties they coincide, but for element-specific defaults (like display on <li> or <a>) they can differ.

A <button> inside a styled <div class="card"> isn't picking up the card's font-family, because browsers give form controls their own default font. Using only a CSS-wide keyword, fix the button's font-family so it matches the surrounding page text.

.card button { font-family: inherit; } — this forces the button to take the computed font-family from its parent, overriding the browser's default form-control font, even though buttons don't inherit font-family automatically in most browser stylesheets.

font-family is an inherited property — you want the button to explicitly take its ancestor's value.