CSS Inheritance
In CSS, some properties automatically inherit their value from the parent element, while others start at their initial (default) value. Understanding which properties inherit and which do not is crucial for writing efficient stylesheets.
Typography-related properties tend to inherit — things like color, font-family, and line-height. Layout properties like margin, padding, and border generally do not inherit — otherwise every nested element would get double margins.
| Inherited Properties | Non-Inherited Properties |
|---|---|
| color | margin |
| font-family | padding |
| font-size | border |
| font-weight | display |
| line-height | width / height |
| text-align | background |
| visibility | position |
| cursor | box-shadow |
| letter-spacing | overflow |
| word-spacing | transform |
| white-space | animation |
| list-style | transition |
| 1 | /* Inheritance in action */ |
| 2 | body { |
| 3 | color: #E0E0E0; /* inherited by all descendant text */ |
| 4 | font-family: "Inter", system-ui, sans-serif; /* inherited */ |
| 5 | font-size: 16px; /* inherited */ |
| 6 | line-height: 1.6; /* inherited */ |
| 7 | } |
| 8 | |
| 9 | /* Child elements automatically use these values */ |
| 10 | p { /* inherits color, font-family, font-size, line-height */ } |
| 11 | span { /* inherits the same values */ } |
| 12 | a { /* inherits, but user-agent overrides color for unvisited links */ } |
| 13 | |
| 14 | /* Non-inherited properties must be set explicitly */ |
| 15 | .card { |
| 16 | margin: 24px; /* NOT inherited — child elements won't get margins */ |
| 17 | padding: 16px; /* NOT inherited */ |
| 18 | border: 1px solid #222; /* NOT inherited */ |
| 19 | display: flex; /* NOT inherited */ |
| 20 | } |
| 21 | |
| 22 | /* Even deeply nested elements don't inherit non-inherited props */ |
| 23 | .card .header .title { |
| 24 | /* margin: 0 (initial), padding: 0 (initial), border: none (initial) */ |
| 25 | } |
The inherit keyword forces a property to inherit its value from the parent element, even for properties that are normally non-inherited. This is useful when you want a child to match its parent's style for a specific property.
| 1 | /* Forcing inheritance on non-inherited properties */ |
| 2 | button { |
| 3 | border: inherit; /* button normally has a UA border, now inherits */ |
| 4 | background: inherit; /* inherits parent background */ |
| 5 | font: inherit; /* inherits all font properties (shorthand) */ |
| 6 | } |
| 7 | |
| 8 | /* Practical example: form elements matching surrounding text */ |
| 9 | .form-control { |
| 10 | font: inherit; /* input inherits parent font instead of UA default */ |
| 11 | color: inherit; /* inherits text color */ |
| 12 | } |
| 13 | |
| 14 | /* Inheriting color on links in a specific context */ |
| 15 | .nav a { |
| 16 | color: inherit; /* instead of the default blue/purple */ |
| 17 | text-decoration: none; |
| 18 | } |
| 19 | |
| 20 | /* Border inheritance for cards inside a themed section */ |
| 21 | .theme-dark .card { |
| 22 | border: 1px solid #333; |
| 23 | } |
| 24 | |
| 25 | .theme-dark .card .inner-card { |
| 26 | border: inherit; /* matches .card's border */ |
| 27 | } |
info
CSS provides four universal keywords that give you fine-grained control over inheritance and reset behavior. Each behaves differently depending on whether the property is inherited or not.
| Keyword | Inherited Property | Non-Inherited Property | Use Case |
|---|---|---|---|
| initial | CSS spec initial value | CSS spec initial value | Hard reset to spec default |
| inherit | Parent value | Parent value | Force parent value |
| unset | Parent value (like inherit) | Initial value (like initial) | Smart reset based on property type |
| revert | Browser default | Browser default | Revert to UA stylesheet |
| revert-layer | Previous cascade layer | Previous cascade layer | Undo current layer's styling |
| 1 | /* initial — hard reset to CSS specification default */ |
| 2 | .no-style { |
| 3 | color: initial; /* black (the spec default) */ |
| 4 | display: initial; /* inline (the spec default for most elements) */ |
| 5 | font-size: initial; /* medium (the spec default) */ |
| 6 | } |
| 7 | |
| 8 | /* unset — smart behavior based on inheritance */ |
| 9 | .card { |
| 10 | margin: unset; /* margin is not inherited → acts as initial (0) */ |
| 11 | color: unset; /* color is inherited → acts as inherit */ |
| 12 | font-family: unset; /* inherited → inherits from parent */ |
| 13 | } |
| 14 | |
| 15 | /* revert — restore browser default styling */ |
| 16 | .link-normal { |
| 17 | color: revert; /* restores default link blue color */ |
| 18 | text-decoration: revert; /* restores default underline */ |
| 19 | } |
| 20 | |
| 21 | /* revert-layer — undo styling from current cascade layer */ |
| 22 | @layer base { |
| 23 | h1 { font-size: 2rem; } |
| 24 | } |
| 25 | |
| 26 | @layer components { |
| 27 | .hero h1 { |
| 28 | font-size: revert-layer; /* goes back to @layer base value */ |
| 29 | } |
| 30 | } |
| 31 | |
| 32 | /* all — shorthand for resetting every property */ |
| 33 | .component-isolation { |
| 34 | all: initial; /* resets ALL properties to initial values */ |
| 35 | } |
| 36 | |
| 37 | .component-soft-reset { |
| 38 | all: unset; /* resets but preserves text inheritance */ |
| 39 | } |
best practice
Beyond the universal keywords, CSS offers several mechanisms to control how properties inherit. The all shorthand resets every property at once. Custom properties (CSS variables) also participate in inheritance — they inherit by default.
1/* The all shorthand */2.reset-this {3 all: initial; /* resets every single property */4 /* Then set only what you need */5 color: #E0E0E0;6 font-family: system-ui;7}8 9/* CSS custom properties inherit by default */10:root {11 --accent: #00FF41;12 --surface: #0D0D0D;13 --text: #E0E0E0;14}15 16.card { background: var(--surface); }17 18.card .title { color: var(--accent); } /* inherits from :root */19 20/* Override inheritance for a subtree */21.dark-section {22 --accent: #FFB000;23 --surface: #111111;24}25/* All children in .dark-section inherit the overridden values */26 27/* Using inherit with custom properties */28.component {29 color: var(--text); /* resolves to inherit from :root or closest parent */30 border-color: var(--accent, #00FF41); /* fallback if --accent not defined */31}Understanding inheritance enables several practical patterns that keep your CSS concise and maintainable. Here are the most useful ones.
Set font, color, and line-height on body once — all text elements inherit it. Override only where needed.
| 1 | body { |
| 2 | font-family: "Inter", system-ui, sans-serif; |
| 3 | font-size: 16px; |
| 4 | line-height: 1.6; |
| 5 | color: #E0E0E0; |
| 6 | } |
| 7 | |
| 8 | /* Only override specific elements */ |
| 9 | h1 { font-size: 2rem; font-weight: 700; } |
| 10 | small { font-size: 0.875rem; color: #808080; } |
Form elements don't inherit font properties by default. Force inheritance for consistent typography.
| 1 | input, textarea, select, button { |
| 2 | font: inherit; /* match the surrounding text */ |
| 3 | color: inherit; |
| 4 | } |
Define theme tokens on :root and let inheritance distribute them. Override at any level for scoped themes.
| 1 | :root { |
| 2 | --bg: #0D0D0D; |
| 3 | --text: #E0E0E0; |
| 4 | --accent: #00FF41; |
| 5 | } |
| 6 | |
| 7 | .card { |
| 8 | background: var(--bg); |
| 9 | color: var(--text); |
| 10 | border: 1px solid var(--accent); |
| 11 | } |
| 12 | |
| 13 | /* Scoped dark/light override */ |
| 14 | .dark-sidebar { |
| 15 | --bg: #0A0A0A; |
| 16 | --accent: #FFB000; |
| 17 | } |
best practice