Docs LogoDocs

CSS Variables - Custom Properties

Documentation for CSS Variables - Custom Properties.

CSS Variables - Custom Properties

What are CSS Variables?

CSS Variables (officially called Custom Properties) allow you to store values that you can reuse throughout your stylesheet. They make your CSS more maintainable, flexible, and easier to update.

Why Use CSS Variables?

CSS Variables provide:

  • Reusability - Define once, use everywhere
  • Easy updates - Change one value, update entire site
  • Dynamic values - Can be changed with JavaScript
  • Better organization - Centralized configuration
  • Theming - Easy dark mode and theme switching

Syntax

Defining variables:

:root {
    --variable-name: value;
}

Using variables:

property: var(--variable-name);
property: var(--variable-name, fallback-value);

Detailed Examples

1. Basic Usage

CSS Example:

:root {
    --primary-color: #007bff;
    --secondary-color: #6c757d;
    --font-size-base: 16px;
    --spacing-unit: 8px;
}

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

.text-secondary {
    color: var(--secondary-color);
}

2. Color Palette

:root {
    /* Primary colors */
    --color-primary: #007bff;
    --color-secondary: #6c757d;
    --color-success: #28a745;
    --color-danger: #dc3545;
    --color-warning: #ffc107;
    --color-info: #17a2b8;
    
    /* Neutral colors */
    --color-white: #ffffff;
    --color-light: #f8f9fa;
    --color-dark: #343a40;
    --color-black: #000000;
    
    /* Text colors */
    --text-primary: #212529;
    --text-secondary: #6c757d;
    --text-muted: #adb5bd;
}

.btn-primary {
    background-color: var(--color-primary);
    color: var(--color-white);
}

.btn-danger {
    background-color: var(--color-danger);
    color: var(--color-white);
}

3. Spacing System

:root {
    --space-xs: 4px;
    --space-sm: 8px;
    --space-md: 16px;
    --space-lg: 24px;
    --space-xl: 32px;
    --space-2xl: 48px;
}

.card {
    padding: var(--space-md);
    margin-bottom: var(--space-lg);
}

.section {
    padding: var(--space-2xl) 0;
}

4. Typography System

:root {
    /* Font families */
    --font-primary: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
    --font-mono: "Courier New", Courier, monospace;
    
    /* Font sizes */
    --font-size-xs: 0.75rem;
    --font-size-sm: 0.875rem;
    --font-size-base: 1rem;
    --font-size-lg: 1.125rem;
    --font-size-xl: 1.25rem;
    --font-size-2xl: 1.5rem;
    --font-size-3xl: 2rem;
    
    /* Font weights */
    --font-weight-normal: 400;
    --font-weight-medium: 500;
    --font-weight-semibold: 600;
    --font-weight-bold: 700;
    
    /* Line heights */
    --line-height-tight: 1.2;
    --line-height-normal: 1.5;
    --line-height-relaxed: 1.7;
}

body {
    font-family: var(--font-primary);
    font-size: var(--font-size-base);
    line-height: var(--line-height-normal);
}

h1 {
    font-size: var(--font-size-3xl);
    font-weight: var(--font-weight-bold);
    line-height: var(--line-height-tight);
}

5. Dark Mode with Variables

:root {
    --bg-primary: #ffffff;
    --bg-secondary: #f8f9fa;
    --text-primary: #212529;
    --text-secondary: #6c757d;
    --border-color: #dee2e6;
}

[data-theme="dark"] {
    --bg-primary: #1a1a1a;
    --bg-secondary: #2d2d2d;
    --text-primary: #f8f9fa;
    --text-secondary: #adb5bd;
    --border-color: #495057;
}

body {
    background-color: var(--bg-primary);
    color: var(--text-primary);
}

.card {
    background-color: var(--bg-secondary);
    border: 1px solid var(--border-color);
}

JavaScript toggle:

// Toggle dark mode
document.documentElement.setAttribute('data-theme', 'dark');

// Toggle back to light
document.documentElement.setAttribute('data-theme', 'light');

6. Fallback Values

.element {
    /* If --primary-color is not defined, use #007bff */
    color: var(--primary-color, #007bff);
    
    /* Nested fallback */
    background: var(--bg-color, var(--fallback-bg, white));
}

7. Scoped Variables

:root {
    --button-padding: 10px 20px;
}

.small-button {
    --button-padding: 5px 10px; /* Override for this scope */
    padding: var(--button-padding);
}

.large-button {
    --button-padding: 15px 30px; /* Override for this scope */
    padding: var(--button-padding);
}

8. Calculated Values

:root {
    --base-size: 16px;
    --scale-ratio: 1.5;
}

.heading {
    font-size: calc(var(--base-size) * var(--scale-ratio));
}

.container {
    --gutter: 20px;
    padding: 0 var(--gutter);
    max-width: calc(1200px + (var(--gutter) * 2));
}

Common Patterns

Pattern 1: Complete Design System

:root {
    /* Colors */
    --primary: #007bff;
    --secondary: #6c757d;
    --success: #28a745;
    --danger: #dc3545;
    
    /* Spacing */
    --space-1: 4px;
    --space-2: 8px;
    --space-3: 12px;
    --space-4: 16px;
    --space-5: 24px;
    
    /* Typography */
    --font-sans: system-ui, sans-serif;
    --font-mono: monospace;
    --text-xs: 0.75rem;
    --text-sm: 0.875rem;
    --text-base: 1rem;
    --text-lg: 1.125rem;
    --text-xl: 1.25rem;
    
    /* Borders */
    --border-radius-sm: 4px;
    --border-radius-md: 8px;
    --border-radius-lg: 12px;
    --border-width: 1px;
    
    /* Shadows */
    --shadow-sm: 0 1px 2px rgba(0,0,0,0.05);
    --shadow-md: 0 4px 6px rgba(0,0,0,0.1);
    --shadow-lg: 0 10px 15px rgba(0,0,0,0.1);
    
    /* Transitions */
    --transition-fast: 150ms;
    --transition-base: 300ms;
    --transition-slow: 500ms;
}

Pattern 2: Component Theming

.button {
    --btn-bg: var(--primary);
    --btn-color: white;
    --btn-padding: var(--space-3) var(--space-4);
    --btn-radius: var(--border-radius-md);
    
    background-color: var(--btn-bg);
    color: var(--btn-color);
    padding: var(--btn-padding);
    border-radius: var(--btn-radius);
}

.button-large {
    --btn-padding: var(--space-4) var(--space-5);
}

.button-small {
    --btn-padding: var(--space-2) var(--space-3);
}

Pattern 3: Responsive Variables

:root {
    --container-width: 100%;
    --font-size-hero: 2rem;
}

@media (min-width: 768px) {
    :root {
        --container-width: 720px;
        --font-size-hero: 3rem;
    }
}

@media (min-width: 1200px) {
    :root {
        --container-width: 1140px;
        --font-size-hero: 4rem;
    }
}

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

.hero-title {
    font-size: var(--font-size-hero);
}

JavaScript Integration

1. Get Variable Value

// Get computed value
const root = document.documentElement;
const primaryColor = getComputedStyle(root)
    .getPropertyValue('--primary-color');

console.log(primaryColor); // "#007bff"

2. Set Variable Value

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

3. Dynamic Theming

const themes = {
    light: {
        '--bg-primary': '#ffffff',
        '--text-primary': '#000000'
    },
    dark: {
        '--bg-primary': '#000000',
        '--text-primary': '#ffffff'
    }
};

function setTheme(themeName) {
    const theme = themes[themeName];
    for (const [property, value] of Object.entries(theme)) {
        document.documentElement.style.setProperty(property, value);
    }
}

setTheme('dark');

Best Practices

  1. Use :root for global variables - Makes them available everywhere
  2. Naming convention - Use descriptive names with hyphens
  3. Group related variables - Colors together, spacing together, etc.
  4. Provide fallbacks - Use var(--color, fallback)
  5. Document your variables - Add comments explaining usage

Last updated on July 15, 2026

On this page