C.W.K.
Stream
Lesson 04 of 05 · published

Inheritance: What Flows Down, What Doesn't, And How To Steer It

~11 min · inheritance, css-properties, inherit, unset, revert

Level 0Markup Novice
0 XP0/34 lessons0/12 achievements
0/100 XP to next level100 XP to go0% complete
"Inheritance is the silent default. Half your styling 'just worked' because of it; the other half is broken because you didn't know which."

The Per-Property Rule

Every CSS property has a single line in its spec: Inherited: yes or Inherited: no. When a parent has a value and the child has no rule setting it:

  • If inherited: the child takes the parent's value.
  • If not inherited: the child uses the property's initial (default) value.

You don't have to memorize the full list — but you do need to internalize the categories.

What Inherits By Default

Typography and text-related properties inherit. The cognitive model: setting font-family on <body> should cascade down to every paragraph, heading, list item, link, span inside without writing 50 rules.

  • color, font (and all its longhand: font-family, font-size, font-weight, etc.)
  • line-height, letter-spacing, word-spacing, text-align, text-indent, text-transform, text-shadow
  • visibility (yes — set visibility on parent and it hides children too)
  • cursor, quotes, list-style (the list bullets cascade to nested lists)
  • Custom properties (CSS variables) — --brand-color: blue; on :root is visible everywhere
  • RTL/LTR-related: direction

What Doesn't Inherit

Layout, box, background, and positional properties don't inherit. The model: you don't want every child to inherit its parent's margin or border or background.

  • margin, padding, border
  • width, height, min-width, max-width, min-height, max-height
  • display, position, top/right/bottom/left
  • background (and all its longhand)
  • flex, grid, all the layout properties
  • transform, opacity, z-index
  • overflow, cursor-inherit (don't confuse with cursor which DOES inherit)

The Form Element Exception

Form elements (<input>, <textarea>, <select>, <button>) historically have UA-provided fonts that override the inheritance from <body>. This is why your beautifully-themed text doesn't apply to form inputs by default. The fix:

The Four Universal Values: inherit, initial, unset, revert

Every CSS property accepts these four keywords (plus revert-layer):

  • inheritforce inheritance from the parent. Useful for properties that don't inherit by default ("I want this padding to match the parent's padding").
  • initial — reset to the property's initial value as defined in the CSS spec. Not the browser's UA-stylesheet value — the spec's initial. (For display, the initial is inline, not whatever the UA gave the element.)
  • unset — if the property inherits by default, behave as inherit; otherwise behave as initial. Useful in resets.
  • revert — revert to the value the property would have if no author rules existed (i.e., back to the UA default, or to the user stylesheet if one exists).
  • revert-layer — revert to the value from the previous cascade layer.
all: revert is the cleanest reset for a single element. One declaration, every property restored to UA defaults. Use when embedding third-party content (an iframe-substitute, an editor preview) that needs to render with default styles even inside a heavily-themed site.

Custom Properties (CSS Variables) Inherit, And It's A Superpower

This is the one that changes how you write CSS in 2026:

Custom properties (--brand-color, --gap, --radius) inherit through the DOM like text properties do. Define them once at :root and they're visible everywhere. Re-declare on a section and that section's subtree sees the new value. This is how dark mode toggles work in modern CSS — data-theme="dark" on <html> redefines the variables, every descendant picks up the new values via inheritance, no extra rules needed.

When Inheritance Bites You

Three classic confusions:

  1. "Why is my child element blue?" — you set color on an ancestor and forgot it inherits.
  2. "Why doesn't my form input use my font?" — form elements override inherited font with UA defaults; add input, button, select, textarea { font: inherit; }.
  3. "Why did the link color change after my reset?" — you set color on a parent and links inherit it, overriding the browser's default link blue.

Pippa's Note

Pippa's theme system is built entirely on inherited custom properties. :root declares --bg, --fg, --accent, etc. [data-theme="dark"] redefines them. Every component reads color: var(--fg), background: var(--bg) — no theme-aware logic anywhere. Switching themes is one attribute change, and inheritance does the rest. Cwk-site's quest colors work the same way: each quest's meta.json palette becomes custom properties on the quest page wrapper, and the components inside inherit them automatically.

Code

Default inheritance, in two snippets·css
/* What inherits by default — typography flows */
body {
  font-family: 'Inter', sans-serif;
  color: #1c2230;
  line-height: 1.6;
}

/* Every <p>, <h1>, <span>, <a> inside <body> picks these up
   with no extra rules — because they all inherit. */

/* What doesn't inherit — layout doesn't flow */
.container { padding: 2rem; background: #f4f6f9; }

/* Children of .container have padding: 0, background: transparent
   by default — even if you'd expect them to inherit. */
inherit, initial, unset, revert·css
/* The form element exception */

/* Without this, your themed font doesn't reach form inputs */
button, input, select, textarea {
  font: inherit;
  color: inherit;
}

/* The keyword zoo */
.box {
  color: inherit;        /* force inherit from parent */
  margin: initial;       /* spec default (0 for margin) */
  padding: unset;        /* not inherited → initial (0) */
  background: revert;    /* revert to UA default (transparent) */
  border: revert-layer;  /* revert to previous cascade layer */
}

/* Universal reset for a third-party widget mount point */
.embed-host {
  all: revert;          /* every property back to UA defaults */
}
Theme system via inherited custom properties·css
/* Custom properties + inheritance = themes */

:root {
  --bg: #ffffff;
  --fg: #1c2230;
  --accent: #5BA3D8;
  --radius: 8px;
  --gap: 1rem;
}

[data-theme="dark"] {
  --bg: #0b0e14;
  --fg: #e7ecf3;
  --accent: #5BA3D8;       /* unchanged */
  /* --radius and --gap inherit from :root, no need to redeclare */
}

/* Every component reads through var() */
body { background: var(--bg); color: var(--fg); }
.btn { background: var(--accent); border-radius: var(--radius); }
.card { padding: var(--gap); border-radius: var(--radius); }

/* Scoping: a section can redefine variables for its own subtree */
.alert { --accent: #d93b3b; }
.alert .btn { /* picks up the new red accent */ }

External links

Exercise

Build a small page with <body>, <main>, <article>, <p>, <form><input>. On <body>, set font-family, color, line-height, and a CSS variable --accent. In the article, define --accent differently. In DevTools → Computed pane, click each element and verify which properties inherited and which didn't. Add a button that toggles data-theme="dark" on <html> with a single class change — confirm every variable-using rule updates.
Hint
If your form input still shows the system font after setting font on body, you forgot to add input { font: inherit; }. Form elements are the perennial inheritance trap.

Progress

Progress is local-only — sign in to sync across devices.
Spotted a bug or have feedback on this page?Report an Issue

Comments 0

🔔 Reply notifications (sign in)
Sign inPlease sign in to comment.

No comments yet — be the first.