CSS variables, also called custom properties, store reusable CSS values under names beginning with --. Define shared values in :root for global use, then retrieve them with var(). A color, spacing value, or font size can be changed once at its definition instead of at every declaration that uses it. section 3.3
Their larger benefit comes from calculation. Combining var() with calc() turns repeated numbers into adjustable design inputs: a base size, ratio, spacing unit, or theme color can drive related values without duplicating the underlying logic. section 3.3 section 3.7
Use custom properties safely in math expressions:
- Store values in px, rem, %, vw, and other units, but ensure the substituted calculation is valid. section 3.3.2
- Multiply or divide a unitless value, such as a scale factor, by a unit-bearing value such as 1rem. section 3.3.2
- Do not multiply or divide two values that both carry units; the resulting CSS math is invalid. section 3.3.2
- Provide a fallback as var(--name, value) when a missing variable should not invalidate the whole property. section 3.3.3
A resilient calculated heading size
A declaration such as font-size: calc(var(--heading-size, 2rem) + 0.5rem) uses the supplied heading size when available and otherwise starts from 2rem. Without that fallback, a missing or invalid variable makes the entire property invalid and the browser ignores it. section 3.3.3
For responsive typography, keep numeric inputs unitless when browser rules make mixed-unit formulas difficult. A base font value, line-height, and width can calculate an article’s font size, line height, and maximum width together. Changing the font input updates the related measurements. section 8.1.2
Listing 8.4 A modular scale based on the golden ratio (1.618)
<head>
<style>
:root {
--ratio: 1.618; #1
--base: 1.25rem; #2
--step-1: calc(var(--base) / var(--ratio)); #3
--step-2: calc(var(--step-1) / var(--ratio)); #4
--step1: calc(var(--base) * var(--ratio)); #4
--step2: calc(var(--step1) * var(--ratio)); #4
--step3: calc(var(--step2) * var(--ratio)); #4
}
h1 { font-size: var(--step3); }
h2 { font-size: var(--step2); }
h3 { font-size: var(--step1); }
p { font-size: var(--base); }
h4 { font-size: var(--step-1); }
h5 { font-size: var(--step-2); }
</style>
</head>
<body>
<h1>Golden ratio scale</h1>
<h2>Golden ratio scale</h2>
<h3>Golden ratio scale</h3>
<p>Golden ratio scale</p>
<h4>Golden ratio scale</h4>
<h5>Golden ratio scale</h5>
</body>
This modular scale makes a base size and ratio visible as reusable inputs. Each smaller or larger step derives from the preceding custom property, then headings and paragraphs consume those named steps. section 8.3.3
Custom properties also support coordinated color modes. Define background and text values at :root, then redefine them inside a prefers-color-scheme: dark media query. The same variable references can produce a different theme without rewriting every consuming rule. section 7.5.5
The practical pattern is simple: name the values that represent design decisions, derive dependent values with calc(), and add fallbacks where a missing input must not discard a declaration. This keeps layout, type, and theme adjustments centralized. section 3.3 section 8.5



