Syntax
--name: value;
var(--name, fallback);Examples
Defining and Using Variables
A typical theming setup using custom properties on :root.
: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);
}Scoped Overrides and Fallbacks
Custom properties respect the cascade, so they can be overridden in specific contexts.
.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 */
}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
At a glance
- Purpose
- Presentation and layout
- File extension
- .css
- Runs in
- Web browsers
- Usually used with
- HTML and JavaScript
Specifications & further reading
Related CSS documentation
Specificity
When multiple CSS rules target the same element with conflicting declarations, specificity determines which one wins. It is calculated as a four-part value: inline styles, ID selectors, class/attribute/pseudo-class selectors, and type/pseudo-element selectors, compared in that order from most to least significant.Cascade Layers (@layer)
@layer lets you explicitly define the priority order between groups of CSS rules, independent of selector specificity. Styles in a layer declared later always beat styles in an earlier layer, regardless of how specific the earlier layer's selectors are - solving specificity conflicts between resets, frameworks, components, and overrides in a predictable, structured way.Media Queries
Media queries apply CSS conditionally based on characteristics of the device or viewport, most commonly width, forming the foundation of responsive design. They use the @media at-rule with a condition, and can be combined with and/or logic to test multiple conditions at once.prefers-color-scheme & prefers-reduced-motion
These media queries detect user system preferences rather than device characteristics. prefers-color-scheme detects whether the user has requested a light or dark theme at the OS level. prefers-reduced-motion detects whether the user has requested minimal animation, important for users with vestibular motion sensitivity.
When multiple CSS rules target the same element with conflicting declarations, specificity determines which one wins. It is calculated as a four-part value: inline styles, ID selectors, class/attribute/pseudo-class selectors, and type/pseudo-element selectors, compared in that order from most to least significant.Cascade Layers (@layer)
@layer lets you explicitly define the priority order between groups of CSS rules, independent of selector specificity. Styles in a layer declared later always beat styles in an earlier layer, regardless of how specific the earlier layer's selectors are - solving specificity conflicts between resets, frameworks, components, and overrides in a predictable, structured way.Media Queries
Media queries apply CSS conditionally based on characteristics of the device or viewport, most commonly width, forming the foundation of responsive design. They use the @media at-rule with a condition, and can be combined with and/or logic to test multiple conditions at once.prefers-color-scheme & prefers-reduced-motion
These media queries detect user system preferences rather than device characteristics. prefers-color-scheme detects whether the user has requested a light or dark theme at the OS level. prefers-reduced-motion detects whether the user has requested minimal animation, important for users with vestibular motion sensitivity.