Syntax
--name: value;
var(--name, fallback);Examples
Defining and Using Variables
A typical theming setup using custom properties on :root.
/* Demo setup: sizing, structure or neutral surfaces. */
.button{border:0;min-height:3rem}
:root {
--primary-color: #3b82f6;
--spacing-unit: 8px;
--border-radius: 6px;
}
.button {
background: var(--primary-color);
padding: calc(var(--spacing-unit) * 2);
border-radius: var(--border-radius);
}- The button’s values are read from custom properties rather than copied into every declaration.
- A closer scope can override a token while another element keeps the root value.
- Change the root token or the scoped override and rerun to see which controls inherit the result.
HTML used by this example
<button class="button">Study plan action</button>Scoped Overrides and Fallbacks
Custom properties respect the cascade, so they can be overridden in specific contexts.
/* Demo setup: sizing, structure or neutral surfaces. */
:root{--primary-color:#c2410c}.button{background:var(--primary-color);padding:1rem;border:0;margin:1rem}.dark-theme{background:#1e293b;padding:1rem}
.dark-theme {
--primary-color: #60a5fa; /* overrides the root value just within this scope */
}
.button {
color: var(--text-color, black); /* falls back to black if --text-color is not defined */
}- The button’s values are read from custom properties rather than copied into every declaration.
- A closer scope can override a token while another element keeps the root value.
- Change the root token or the scoped override and rerun to see which controls inherit the result.
HTML used by this example
<button class="button">Root scope</button><section class="dark-theme"><button class="button">Overridden scope</button></section>Parameters and values
- --name: value; (declaration): Defines a custom property, commonly on :root for global scope
- var(--name) (function): Reads a custom property's current value
- var(--name, fallback) (function): Uses a fallback if the custom property is not defined
Best practices
- Define global theme variables on :root, and override them locally on specific components or contexts (like a .dark-theme class) as needed
- Provide a fallback value in var() for properties that might not always be defined, like var(--gap, 1rem)
- Take advantage of custom properties being live and JavaScript-readable for dynamic theming without regenerating an entire stylesheet
- Use meaningful, consistent naming conventions (--color-primary, --spacing-sm) as a project grows, similar to a design token system
Browser compatibility
- chrome
- Yes
- firefox
- Yes
- safari
- Yes
- edge
- Yes
These are the existing reference’s support labels, not tested minimum versions. Individual values and APIs can have different support. Check the linked specification before choosing a browser target.
CSS specifications (modules)