Go Back

CSS Variables

Definition

CSS Variables (officially called CSS Custom Properties) are entities defined by developers that contain specific values to be reused throughout a stylesheet. They follow the syntax --variable-name: value; when defined and are accessed using the var(--variable-name) function. Unlike preprocessor variables (like those in Sass or Less), CSS Variables are part of the actual CSS specification, are resolved at runtime rather than compile time, cascade through the DOM, and can be manipulated with JavaScript.

Basic Syntax and Usage

CSS Variables follow specific syntactic rules:

Defining Variables

:root {
  --primary-color: #3498db;
  --secondary-color: #2ecc71;
  --base-font-size: 16px;
  --spacing-unit: 8px;
}

Using Variables

.button {
  background-color: var(--primary-color);
  padding: var(--spacing-unit) calc(var(--spacing-unit) * 2);
  font-size: var(--base-font-size);
}

Fallback Values

.element {
  color: var(--undefined-color, #333);
}

Local Scope Variables

.component {
  --component-padding: 20px;
  padding: var(--component-padding);
}

Key Characteristics of CSS Variables

CSS Variables have several important properties that distinguish them from preprocessor variables:

  1. Runtime Evaluation: Computed at runtime, allowing dynamic changes
  2. DOM Cascading: Follow the normal cascading rules of CSS
  3. Inheritance: Values inherit to descendant elements
  4. Scope: Can be scoped to specific elements or globally using :root
  5. JavaScript Access: Can be read and modified using JavaScript
  6. Responsive Capabilities: Can be changed within media queries
  7. Real DOM Properties: They exist as actual properties on DOM elements

Use Cases and Applications

CSS Variables are particularly valuable in several scenarios:

  • Theme Systems: Creating light/dark modes or brand variations
  • Responsive Design: Adjusting values at different breakpoints
  • Component Libraries: Providing customization options for components
  • Animation: Animating between variable values
  • Dynamic Styling: Changing styles based on user interaction
  • Maintaining Design Systems: Centralizing design decisions
  • Simplifying Complex Calculations: Using variables in calc() expressions
  • Reducing Repetition: Defining common values in one place

Theme Implementation with CSS Variables

A common implementation pattern for theming:

/* Define theme variables */
:root {
  /* Light theme (default) */
  --background-color: #ffffff;
  --text-color: #333333;
  --accent-color: #0066cc;
}

/* Dark theme */
[data-theme="dark"] {
  --background-color: #1a1a1a;
  --text-color: #f0f0f0;
  --accent-color: #3399ff;
}

/* Apply theme variables */
body {
  background-color: var(--background-color);
  color: var(--text-color);
}

.button {
  background-color: var(--accent-color);
}

Manipulating CSS Variables with JavaScript

CSS Variables can be dynamically changed using JavaScript:

// Get variable value
const rootStyles = getComputedStyle(document.documentElement);
const currentColor = rootStyles.getPropertyValue('--primary-color').trim();

// Set variable value
document.documentElement.style.setProperty('--primary-color', '#ff0000');

// Change variables based on user interaction
document.getElementById('slider').addEventListener('input', function(e) {
  document.documentElement.style.setProperty('--spacing-unit', e.target.value + 'px');
});

CSS Variables vs. Preprocessor Variables

Key differences between native CSS Variables and preprocessor variables (Sass, Less):

Aspect CSS Variables Preprocessor Variables
Runtime Changes Dynamic (can change at runtime) Static (resolved at compile time)
DOM Access Available to JavaScript Not available after compilation
Cascade Follow CSS inheritance rules No concept of inheritance
Scope Scoped to selectors Scoped to files or blocks
Browser Support Modern browsers (IE11 requires polyfill) All browsers (compiles to standard CSS)
Computation Computed in browser Computed during build process

Advanced Techniques with CSS Variables

CSS Variables enable sophisticated styling techniques:

Calculated Properties

:root {
  --base-size: 16px;
}

h1 { font-size: calc(var(--base-size) * 2.5); }
h2 { font-size: calc(var(--base-size) * 2); }
h3 { font-size: calc(var(--base-size) * 1.5); }

Variable Composition

:root {
  --hue: 220;
  --saturation: 50%;
  --lightness: 50%;
  --primary-color: hsl(var(--hue), var(--saturation), var(--lightness));
}

CSS Variables in Media Queries

:root {
  --content-width: 100%;
}

@media (min-width: 768px) {
  :root {
    --content-width: 750px;
  }
}

.container {
  width: var(--content-width);
}

Performance Considerations

When using CSS Variables, consider these performance aspects:

  • Recalculation Cost: Changing variables triggers style recalculations
  • Specificity Management: Higher specificity overrides can increase complexity
  • Fallback Processing: Browsers must evaluate fallback values when variables are invalid
  • Deep Nesting: Deeply nested variables referencing other variables can impact performance
  • Size Efficiency: Can reduce overall CSS size by eliminating repetition

Browser Support and Polyfills

  • Modern Browsers: Full support in all modern browsers
  • Legacy Support: IE11 requires polyfills with limitations
  • Graceful Degradation: Using fallback values for unsupported browsers
  • Feature Detection: Can test for support with @supports (--custom-property: value) { ... }

Best Practices for CSS Variables

Effective use of CSS Variables involves:

  1. Naming Conventions: Using clear, consistent naming patterns
  2. Organization: Grouping related variables together
  3. Documentation: Commenting variable purpose and usage
  4. Fallbacks: Providing fallback values for critical properties
  5. Scoping: Using appropriate scope for variables rather than making everything global
  6. Moderation: Not overusing variables for single-use values
  7. Semantic Naming: Using names that reflect purpose, not specific values
  8. Layering: Creating systems of variables that reference other variables

By providing a native way to create reusable, dynamic values in CSS, Custom Properties have fundamentally changed how developers structure and maintain stylesheets, enabling more sophisticated, maintainable, and adaptable front-end code.