LearnContact
Lesson 2422 min read

CSS Variables

Learn how CSS variables create reusable, maintainable, and dynamic styles using custom properties, the var() function, scope, inheritance, fallback values, themes, calculations, and JavaScript.

Introduction

Large websites often reuse the same colors, spacing values, font sizes, border radiuses, and other design values in many places.

Writing the same value repeatedly makes CSS harder to update and maintain.

CSS Variables allow reusable values to be stored once and used throughout a stylesheet.

Define Variable
Store CSS Value
Use var()
Reuse Value
Change Variable
Update Matching Styles
One Value, Many Uses

A CSS variable can store a reusable value such as a color, spacing size, font family, shadow, or even a complete gradient.

What are CSS Variables?

CSS Variables, officially called Custom Properties, are reusable values defined using names that begin with two hyphens.

CSS Variable
--primary-color: #6c5ce7;

The stored value can later be accessed using the var() function.

Using the Variable
color: var(--primary-color);

Why Do We Need CSS Variables?

Reusability

Use the same design value in many CSS rules.

Easy Maintenance

Change one variable instead of editing many declarations.

Consistent Design

Keep colors, spacing, and typography consistent.

Themes

Create light, dark, and custom themes.

Responsive Values

Change variables at different breakpoints.

Dynamic Styling

Update CSS values using JavaScript.

Real-World Analogy

Imagine a company uses one official brand color everywhere.

Instead of telling every designer to remember the exact color code, the company gives the color a name: Brand Purple.

Whenever the official color changes, the company changes the definition of Brand Purple once instead of updating every design manually.

Company Design SystemCSS
Brand Purple--primary-color
Official color value#6c5ce7
Use brand colorvar(--primary-color)
Change brand definitionUpdate variable value
All designs use new valueAll matching CSS updates

CSS Variable Syntax

Syntax
selector {
    --variable-name: value;
}
Example
:root {
    --primary-color: #6c5ce7;
}
PartPurpose
:rootDefines where the variable is available
--Required beginning of a custom property name
primary-colorCustom variable name
:Separates the property name and value
#6c5ce7Stored CSS value

Creating a CSS Variable

A CSS variable is created like a normal CSS property, but its name must begin with two hyphens.

Creating Variables
.card {
    --card-color: #6c5ce7;

    --card-padding: 24px;

    --card-radius: 16px;
}
Two Hyphens Are Required

Custom property names must begin with two hyphens, such as --primary-color.

The var() Function

The var() function reads the value stored inside a CSS custom property.

var() Syntax
property: var(--variable-name);
Example
.button {
    background:
        var(--primary-color);
}

Example 1: Reusing a Color

Without CSS Variables
.heading {
    color: #6c5ce7;
}

.button {
    background: #6c5ce7;
}

.link {
    color: #6c5ce7;
}

.card {
    border-color: #6c5ce7;
}
With CSS Variables
:root {
    --primary-color: #6c5ce7;
}

.heading {
    color:
        var(--primary-color);
}

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

.link {
    color:
        var(--primary-color);
}

.card {
    border-color:
        var(--primary-color);
}

Global Variables

A global variable is defined in a location where it can be inherited and used throughout the document.

The :root selector is commonly used to define global CSS variables.

The :root Selector

The :root pseudo-class selects the root element of the document. In HTML, this is the html element.

Global Variables
:root {
    --primary-color: #6c5ce7;

    --secondary-color: #00b894;

    --text-color: #2d3436;

    --spacing: 20px;
}
Why Use :root?

Variables defined on :root are commonly available throughout the page through CSS inheritance.

Example 2: Global Variables

CSS
:root {
    --primary: #6c5ce7;

    --text: #2d3436;

    --space: 20px;

    --radius: 12px;
}

.card {
    padding: var(--space);

    color: var(--text);

    border:
        2px solid
        var(--primary);

    border-radius:
        var(--radius);
}

.button {
    padding:
        12px var(--space);

    background:
        var(--primary);

    border-radius:
        var(--radius);
}

Local Variables

A local variable is defined on a specific element or selector and is available to that element and its descendants.

Local Variable
.card {
    --card-color: #00b894;

    background:
        var(--card-color);
}

Example 3: Local Scope

HTML
<div class="product-card">
    <h3>Product</h3>

    <button>
        Buy Now
    </button>
</div>
CSS
.product-card {
    --accent-color: #00b894;

    border:
        2px solid
        var(--accent-color);
}

.product-card h3 {
    color:
        var(--accent-color);
}

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

Variable Scope

Scope determines where a CSS variable can be used.

Variable Scope
:root
│
├── Global Variables
│
├── Header
│   └── Can Use Global Variables
│
├── Main
│   │
│   └── .card
│       │
│       ├── Local Variable
│       ├── Heading Can Use It
│       └── Button Can Use It
│
└── Footer
    └── Cannot Use .card Local Variable
Variable LocationAvailable To
:rootMost elements through inheritance
bodyBody and its descendants
.cardThe card and its descendants
.buttonThe button and its descendants

CSS Variable Inheritance

Custom properties normally inherit from parent elements to their descendants.

Inheritance
.parent {
    --text-color: #6c5ce7;
}

.child {
    color:
        var(--text-color);
}
Variable Defined on Parent
Child Searches for Variable
No Local Value Found
Inherit Parent Value
Use Variable

Overriding Variables

A variable can be redefined in a more specific scope.

Variable Override
:root {
    --card-color: #6c5ce7;
}

.special-card {
    --card-color: #00b894;
}

Example 4: Overriding Variables

HTML
<div class="card">
    Normal Card
</div>

<div class="card special">
    Special Card
</div>
CSS
:root {
    --card-bg: #6c5ce7;
}

.card {
    background:
        var(--card-bg);

    color: white;
}

.special {
    --card-bg: #00b894;
}

Fallback Values

The var() function can include a fallback value that is used when the requested custom property is not defined or is invalid in the relevant context.

Fallback Syntax
var(
    --variable-name,
    fallback-value
)
Example
.button {
    background:
        var(
            --button-color,
            #6c5ce7
        );
}

Example 5: Fallback Value

CSS
.message {
    color:
        var(
            --message-color,
            #0984e3
        );
}

If --message-color is not available, the browser uses #0984e3.

Fallbacks Improve Resilience

Fallback values are useful when a component may receive optional custom properties.

Variables for Colors

Color Variables
:root {
    --color-primary: #6c5ce7;

    --color-secondary: #00b894;

    --color-danger: #d63031;

    --color-warning: #fdcb6e;

    --color-text: #2d3436;

    --color-muted: #636e72;

    --color-background: #ffffff;
}

Variables for Spacing

Spacing Scale
:root {
    --space-xs: 4px;

    --space-sm: 8px;

    --space-md: 16px;

    --space-lg: 24px;

    --space-xl: 40px;

    --space-2xl: 64px;
}

Variables for Typography

Typography Variables
:root {
    --font-family:
        Arial,
        sans-serif;

    --font-size-sm: 0.875rem;

    --font-size-base: 1rem;

    --font-size-lg: 1.25rem;

    --font-size-title: 3rem;

    --font-weight-normal: 400;

    --font-weight-bold: 700;
}

Variables for Borders

Border Variables
:root {
    --border-color: #dfe6e9;

    --border-width: 1px;

    --radius-sm: 6px;

    --radius-md: 12px;

    --radius-lg: 20px;

    --radius-full: 999px;
}

Variables for Shadows

Shadow Variables
:root {
    --shadow-sm:
        0 2px 8px
        rgba(0, 0, 0, 0.08);

    --shadow-md:
        0 8px 24px
        rgba(0, 0, 0, 0.12);

    --shadow-lg:
        0 20px 50px
        rgba(0, 0, 0, 0.16);
}

Design Tokens

Design tokens are named values that represent reusable design decisions such as colors, spacing, typography, borders, and shadows.

Design Token Structure
Design System
│
├── Colors
│   ├── --color-primary
│   ├── --color-success
│   └── --color-danger
│
├── Spacing
│   ├── --space-sm
│   ├── --space-md
│   └── --space-lg
│
├── Typography
│   ├── --font-size-sm
│   ├── --font-size-base
│   └── --font-size-lg
│
└── Effects
    ├── --radius-md
    └── --shadow-md

Example 6: Design System

CSS
:root {
    --color-primary: #6c5ce7;

    --color-text: #2d3436;

    --color-surface: #ffffff;

    --space-sm: 8px;

    --space-md: 16px;

    --space-lg: 24px;

    --radius: 12px;

    --shadow:
        0 10px 30px
        rgba(0, 0, 0, 0.1);
}

.card {
    padding:
        var(--space-lg);

    background:
        var(--color-surface);

    color:
        var(--color-text);

    border-radius:
        var(--radius);

    box-shadow:
        var(--shadow);
}

.card button {
    padding:
        var(--space-sm)
        var(--space-md);

    background:
        var(--color-primary);

    border-radius:
        var(--radius);
}

CSS Variables and calc()

CSS variables can be used inside the calc() function to create calculated values.

Variable with calc()
:root {
    --sidebar-width: 250px;
}

.main {
    width:
        calc(
            100% -
            var(--sidebar-width)
        );
}

Example 7: Dynamic Calculation

CSS
.layout {
    --gap: 20px;

    display: grid;

    gap:
        var(--gap);
}

.large-space {
    margin-top:
        calc(
            var(--gap) * 2
        );
}

CSS Variables and Media Queries

A media query can redefine a CSS variable instead of repeating many complete declarations.

Responsive Variables
:root {
    --section-padding: 30px;

    --title-size: 2rem;
}

@media (min-width: 768px) {
    :root {
        --section-padding: 60px;

        --title-size: 3rem;
    }
}

@media (min-width: 1200px) {
    :root {
        --section-padding: 100px;

        --title-size: 4rem;
    }
}

Example 8: Responsive Variables

CSS
.responsive-section {
    --section-space: 30px;

    --heading-size: 2rem;

    padding:
        var(--section-space);
}

.responsive-section h2 {
    font-size:
        var(--heading-size);
}

@media (min-width: 768px) {
    .responsive-section {
        --section-space: 60px;

        --heading-size: 3rem;
    }
}

Creating Themes

CSS variables are commonly used to create themes because a small group of variables can control the appearance of many components.

Theme Variables
:root {
    --bg-color: #ffffff;

    --text-color: #2d3436;

    --card-color: #f5f6fa;
}

[data-theme="dark"] {
    --bg-color: #1e272e;

    --text-color: #f5f6fa;

    --card-color: #2d3436;
}

Example 9: Light and Dark Theme

HTML
<div class="theme-card">
    <h3>Theme Card</h3>

    <p>
        The appearance is controlled
        by CSS variables.
    </p>
</div>
CSS
:root {
    --page-bg: #ffffff;

    --page-text: #2d3436;

    --card-bg: #f5f6fa;
}

.dark-theme {
    --page-bg: #1e272e;

    --page-text: #f5f6fa;

    --card-bg: #2d3436;
}

.theme-card {
    background:
        var(--card-bg);

    color:
        var(--page-text);
}

Component Variables

Reusable components can expose custom properties that allow their appearance to be customized without rewriting the complete component CSS.

Component Variables
.button {
    background:
        var(
            --button-bg,
            #6c5ce7
        );

    color:
        var(
            --button-text,
            white
        );

    border-radius:
        var(
            --button-radius,
            8px
        );
}

Example 10: Reusable Button

HTML
<button class="button">
    Primary
</button>

<button class="button success">
    Success
</button>

<button class="button danger">
    Danger
</button>
CSS
.button {
    --button-bg: #6c5ce7;

    padding:
        12px 20px;

    border: none;

    background:
        var(--button-bg);

    color: white;

    border-radius: 8px;
}

.success {
    --button-bg: #00b894;
}

.danger {
    --button-bg: #d63031;
}

Nested Fallback Values

A fallback value can itself contain another var() function.

Nested Fallback
.button {
    background:
        var(
            --button-color,
            var(
                --primary-color,
                #6c5ce7
            )
        );
}
Check --button-color
Not Found?
Check --primary-color
Not Found?
Use #6c5ce7

Using Variables in Gradients

Gradient Variables
:root {
    --gradient-start: #6c5ce7;

    --gradient-end: #00b894;
}

.hero {
    background:
        linear-gradient(
            135deg,
            var(--gradient-start),
            var(--gradient-end)
        );
}

Using Variables in Transitions

Transition Variables
:root {
    --transition-fast:
        0.2s ease;

    --transition-normal:
        0.4s ease;
}

.button {
    transition:
        transform
        var(--transition-fast);
}

Using Variables in Animations

Animation Variables
.loader {
    --animation-duration: 1s;

    animation:
        spin
        var(--animation-duration)
        linear
        infinite;
}

Different elements can override the animation variable while reusing the same animation definition.

CSS Variables with JavaScript

Unlike many preprocessor variables, CSS custom properties exist in the browser and can be changed dynamically with JavaScript.

Changing a Variable
document.documentElement.style.setProperty(
    '--primary-color',
    '#00b894'
);

Example 11: Change Variable with JavaScript

HTML
<button id="changeColor">
    Change Color
</button>
CSS
:root {
    --primary-color: #6c5ce7;
}

button {
    background:
        var(--primary-color);
}
JavaScript
const button =
    document.getElementById(
        'changeColor'
    );

button.addEventListener(
    'click',
    () => {
        document.documentElement
            .style
            .setProperty(
                '--primary-color',
                '#00b894'
            );
    }
);

Reading Variables with JavaScript

Reading a CSS Variable
const styles =
    getComputedStyle(
        document.documentElement
    );

const primaryColor =
    styles.getPropertyValue(
        '--primary-color'
    );

console.log(primaryColor);
JavaScript MethodPurpose
setProperty()Creates or changes a CSS custom property
getPropertyValue()Reads a CSS custom property
removeProperty()Removes an inline custom property

Complete Theme Switcher Example

The following example combines global variables, component variables, theme overrides, transitions, reusable design tokens, and JavaScript.

HTML
<div
    class="theme-app"
    id="themeApp"
>
    <nav class="theme-nav">
        <strong>
            PrograMinds
        </strong>

        <button id="themeToggle">
            🌙 Dark Mode
        </button>
    </nav>

    <section class="theme-hero">
        <span class="theme-badge">
            CSS Variables
        </span>

        <h1>
            Build Dynamic Themes
        </h1>

        <p>
            Change a few variables and
            update the appearance of an
            entire interface.
        </p>

        <div class="theme-actions">
            <button class="primary">
                Start Learning
            </button>

            <button class="secondary">
                Explore Course
            </button>
        </div>
    </section>

    <section class="theme-cards">
        <article>
            <span>🎨</span>

            <h3>
                Reusable Colors
            </h3>

            <p>
                Define design values once
                and use them everywhere.
            </p>
        </article>

        <article>
            <span>🌙</span>

            <h3>
                Dynamic Themes
            </h3>

            <p>
                Switch complete themes by
                changing custom properties.
            </p>
        </article>

        <article>
            <span>⚡</span>

            <h3>
                JavaScript Control
            </h3>

            <p>
                Update CSS variables while
                the page is running.
            </p>
        </article>
    </section>
</div>
CSS
.theme-app {
    --color-primary: #6c5ce7;

    --color-secondary: #00b894;

    --color-background: #f8f9ff;

    --color-surface: #ffffff;

    --color-text: #2d3436;

    --color-muted: #636e72;

    --color-border: #dfe6e9;

    --space-sm: 8px;

    --space-md: 16px;

    --space-lg: 24px;

    --space-xl: 48px;

    --radius-sm: 8px;

    --radius-md: 16px;

    --shadow:
        0 15px 40px
        rgba(0, 0, 0, 0.1);

    --transition:
        0.3s ease;

    padding:
        var(--space-lg);

    background:
        var(--color-background);

    color:
        var(--color-text);

    border-radius:
        var(--radius-md);

    transition:
        background
        var(--transition),
        color
        var(--transition);
}

.theme-app.dark {
    --color-primary: #a29bfe;

    --color-secondary: #55efc4;

    --color-background: #1e272e;

    --color-surface: #2d3436;

    --color-text: #f5f6fa;

    --color-muted: #b2bec3;

    --color-border: #636e72;

    --shadow:
        0 15px 40px
        rgba(0, 0, 0, 0.35);
}

.theme-nav {
    display: flex;

    align-items: center;

    justify-content:
        space-between;

    gap:
        var(--space-md);
}

.theme-nav strong {
    color:
        var(--color-primary);

    font-size: 1.5rem;
}

.theme-nav button {
    padding:
        10px 16px;

    border:
        1px solid
        var(--color-border);

    background:
        var(--color-surface);

    color:
        var(--color-text);

    border-radius:
        var(--radius-sm);

    cursor: pointer;

    transition:
        all
        var(--transition);
}

.theme-hero {
    padding:
        80px 0;

    text-align: center;
}

.theme-badge {
    display: inline-block;

    padding:
        var(--space-sm)
        var(--space-md);

    background:
        color-mix(
            in srgb,
            var(--color-primary) 15%,
            transparent
        );

    color:
        var(--color-primary);

    border-radius: 999px;

    font-weight: 700;
}

.theme-hero h1 {
    max-width: 800px;

    margin:
        var(--space-lg)
        auto;

    font-size:
        clamp(
            2.5rem,
            8vw,
            5rem
        );

    line-height: 1.05;
}

.theme-hero p {
    max-width: 650px;

    margin-inline: auto;

    color:
        var(--color-muted);

    font-size: 1.1rem;

    line-height: 1.7;
}

.theme-actions {
    display: flex;

    flex-wrap: wrap;

    justify-content: center;

    gap:
        var(--space-md);

    margin-top:
        var(--space-lg);
}

.theme-actions button {
    padding:
        14px 24px;

    border:
        2px solid
        var(--color-primary);

    border-radius:
        var(--radius-sm);

    font-weight: 700;

    cursor: pointer;

    transition:
        all
        var(--transition);
}

.theme-actions .primary {
    background:
        var(--color-primary);

    color: white;
}

.theme-actions .secondary {
    background:
        transparent;

    color:
        var(--color-primary);
}

.theme-actions button:hover {
    transform:
        translateY(-3px);
}

.theme-cards {
    display: grid;

    grid-template-columns:
        repeat(
            auto-fit,
            minmax(220px, 1fr)
        );

    gap:
        var(--space-lg);
}

.theme-cards article {
    padding:
        var(--space-lg);

    background:
        var(--color-surface);

    border:
        1px solid
        var(--color-border);

    border-radius:
        var(--radius-md);

    box-shadow:
        var(--shadow);

    transition:
        all
        var(--transition);
}

.theme-cards article:hover {
    transform:
        translateY(-8px);
}

.theme-cards article > span {
    font-size: 2.5rem;
}

.theme-cards p {
    color:
        var(--color-muted);

    line-height: 1.6;
}
JavaScript
const themeApp =
    document.getElementById(
        'themeApp'
    );

const themeToggle =
    document.getElementById(
        'themeToggle'
    );

themeToggle.addEventListener(
    'click',
    () => {
        themeApp.classList.toggle(
            'dark'
        );

        const isDark =
            themeApp.classList.contains(
                'dark'
            );

        themeToggle.textContent =
            isDark
                ? '☀️ Light Mode'
                : '🌙 Dark Mode';
    }
);

Browser Processing Flow

Browser Reads CSS
Find Custom Property
Store Variable Value
Find var() Function
Resolve Variable Scope
Check Local Value
Check Inherited Value
Check Fallback
Apply Final Value
Render Element
Variable Resolution
var(--primary-color)
        │
        ▼
Check Current Element
        │
    Value Found?
     ┌──┴──┐
     │     │
    Yes    No
     │     │
     ▼     ▼
   Use It  Check Parent
             │
         Value Found?
          ┌──┴──┐
          │     │
         Yes    No
          │     │
          ▼     ▼
        Use It  Use Fallback
                  │
                  ▼
             Apply Final Value

CSS Variables vs Preprocessor Variables

CSS Variables

  • Run in the browser.
  • Can change dynamically.
  • Participate in inheritance.
  • Have CSS scope.
  • Can be changed with JavaScript.
  • Can change inside media queries.

Preprocessor Variables

  • Usually resolved before browser execution.
  • Compiled into normal CSS values.
  • Do not use normal CSS inheritance.
  • Cannot normally change at runtime.
  • Require a preprocessing tool.
  • Useful for build-time logic.

Real-World Applications

Design Systems

Store reusable colors, spacing, typography, and effects.

Theme Switching

Create light, dark, and custom themes.

Components

Allow reusable components to expose customizable values.

Responsive Design

Change shared values at different breakpoints.

Branding

Maintain consistent brand colors across a website.

Dynamic Interfaces

Update styles with JavaScript while the page is running.

Dashboards

Control theme colors and layout dimensions.

E-Commerce

Reuse product, status, pricing, and promotional styles.

Advantages

Reusable Values

Define important values once and reuse them.

Easy Updates

Change one variable to update many styles.

Consistency

Maintain a consistent visual system.

Dynamic Themes

Create theme variations with small overrides.

Inheritance

Variables can flow from parent elements to descendants.

Runtime Changes

JavaScript can read and update custom properties.

Common Beginner Mistakes

Forgetting the Two Hyphens

Custom property names must begin with --.

Using the Variable Without var()

A custom property value is normally accessed with the var() function.

Forgetting the Variable Scope

A local variable is not automatically available everywhere.

Assuming Variables Are Global

Variables are available according to the CSS cascade and inheritance.

Case Mismatch

Custom property names are case-sensitive.

Missing Fallback Values

Optional component variables may benefit from safe defaults.

Using Unclear Names

Names such as --x or --blue2 make large stylesheets difficult to understand.

Naming by Current Value

A variable named --blue may become confusing if the design later changes it to purple.

Defining Everything Globally

Component-specific values can often remain inside the component scope.

Creating Too Many Variables

Not every single CSS value needs to become a custom property.

Repeating the Same Variable Names Randomly

Use a consistent naming system for design tokens.

Ignoring Inheritance

A child may receive a custom property value from a parent.

Unexpected Overrides

A closer or more specific variable definition can replace an inherited value.

Invalid Variable Values

The stored value must still be valid when used by the final CSS property.

Confusing Fallbacks with Browser Support

A var() fallback handles missing or invalid custom properties, not unsupported CSS features in general.

Hardcoding Values Beside Variables

Inconsistent use reduces the maintenance benefits of a variable system.

Overusing JavaScript

Use CSS inheritance and selectors when they can solve the problem without scripting.

Forgetting Theme Contrast

Theme variables must preserve readable color contrast.

Changing Only Background Colors

A theme may also need text, borders, shadows, and interactive state variables.

Creating Circular References

Variables should not depend on each other in an unresolved circular chain.

Best Practices

  • Use CSS variables for values that are reused or intentionally customizable.
  • Use clear and descriptive custom property names.
  • Always begin custom property names with two hyphens.
  • Use var() to access stored custom property values.
  • Define broadly shared variables on :root when appropriate.
  • Keep component-specific variables close to their components.
  • Understand the scope of every custom property.
  • Remember that custom properties normally inherit.
  • Use inheritance intentionally.
  • Override variables at the smallest useful scope.
  • Avoid unnecessary global variables.
  • Group related variables logically.
  • Create consistent naming conventions.
  • Use semantic names when the purpose matters more than the current value.
  • Prefer --color-primary over --purple when the value represents a brand role.
  • Use names such as --color-success and --color-danger for semantic states.
  • Use predictable prefixes for related variables.
  • Use a consistent spacing scale.
  • Use a consistent typography scale.
  • Use a consistent border-radius scale.
  • Use reusable shadow variables.
  • Use design tokens for important design decisions.
  • Avoid turning every CSS declaration into a variable.
  • Create variables when reuse, consistency, customization, or dynamic behavior provides value.
  • Use fallback values for optional component variables.
  • Choose meaningful fallback values.
  • Use nested fallbacks only when the fallback chain remains understandable.
  • Remember that custom property names are case-sensitive.
  • Keep variable names consistent across the project.
  • Document unusual or important design tokens.
  • Avoid unexplained abbreviations.
  • Use variables for theme colors.
  • Include background, surface, text, muted text, border, and accent colors in theme systems.
  • Test color contrast in every theme.
  • Do not assume one text color works on every theme background.
  • Use theme overrides instead of duplicating entire stylesheets.
  • Change variables at a parent element to theme an entire section.
  • Use data attributes or classes for theme states.
  • Use JavaScript only when runtime interaction is required.
  • Use setProperty() to change custom properties dynamically.
  • Use getPropertyValue() to read computed custom properties.
  • Use removeProperty() when an inline override should be removed.
  • Avoid unnecessary direct style changes when changing a class can control the same theme.
  • Use variables with calc() for reusable calculations.
  • Keep calc() expressions readable.
  • Use variables inside gradients when colors are reusable.
  • Use variables for transition timing when motion should remain consistent.
  • Use variables for animation duration when components need different speeds.
  • Use media queries to redefine shared responsive values.
  • Avoid repeating many declarations when changing one variable can produce the same result.
  • Use responsive variables for spacing and typography when appropriate.
  • Combine CSS variables with clamp() for flexible values.
  • Combine CSS variables with min() and max() when useful.
  • Use component-level variables as a customization API.
  • Provide sensible defaults for reusable components.
  • Allow component variants to override variables.
  • Avoid duplicating complete component rules for small visual differences.
  • Keep global design tokens separate from component-specific variables when useful.
  • Use a naming structure that scales with the project.
  • Keep raw design values and semantic values separate in larger design systems when necessary.
  • Use variables consistently after introducing them.
  • Avoid mixing hardcoded and variable-based values without a reason.
  • Inspect variable values in browser developer tools.
  • Check which element defines the active variable.
  • Check inherited values when debugging unexpected styles.
  • Remember that the CSS cascade also affects custom properties.
  • Consider specificity and source order when variables are overridden.
  • Use local overrides instead of !important when possible.
  • Test fallback behavior.
  • Test theme switching.
  • Test responsive variable changes.
  • Test JavaScript-driven variable changes.
  • Test themes with all component states.
  • Test hover, focus, active, disabled, success, warning, and error states.
  • Keep theme transitions subtle.
  • Respect reduced-motion preferences for large animated theme changes.
  • Avoid storing unrelated values inside one unclear variable.
  • Keep variable values valid for the properties where they are used.
  • Remember that one custom property can store complex values.
  • Use complete shadows, gradients, and transition values when reuse is helpful.
  • Avoid circular custom property references.
  • Keep dependency chains understandable.
  • Use CSS variables as part of a maintainable design system.
  • Review unused variables as the project evolves.
  • Remove obsolete design tokens.
  • Keep naming stable when variables are part of a reusable component API.
  • Use variables to reduce duplication, not to make simple CSS unnecessarily abstract.
  • Prefer understandable CSS over excessive abstraction.
  • Use custom properties to create flexible, reusable, and maintainable interfaces.
Remember the CSS Variable Formula

Define a custom property with --name, store a reusable value, access it with var(--name), and override the variable when the design needs to change.

Frequently Asked Questions

What is a CSS variable?

A CSS variable is a custom property that stores a reusable CSS value.

What is the official name for CSS variables?

They are officially called CSS Custom Properties.

How do I create a CSS variable?

Create a custom property whose name begins with two hyphens, such as --primary-color.

How do I use a CSS variable?

Use the var() function, such as color: var(--primary-color).

Why do variable names start with --?

The two hyphens identify the property as a CSS custom property.

What does :root mean?

The :root pseudo-class selects the document root element and is commonly used for globally shared variables.

Are CSS variables global?

Only variables defined in a broadly inherited scope such as :root are commonly available throughout the document.

Can CSS variables be local?

Yes. A variable defined on a component is available to that element and its descendants according to inheritance.

Do CSS variables inherit?

Custom properties normally inherit from parent elements.

Can I override a CSS variable?

Yes. Redefine the custom property in a more appropriate scope.

Are CSS variable names case-sensitive?

Yes. --main-color and --Main-Color are different custom properties.

What is a fallback value?

A fallback is an alternative value used when the requested custom property cannot provide a usable value.

How do I add a fallback?

Use a second argument in var(), such as var(--color, blue).

Can fallbacks contain another variable?

Yes. A fallback can contain another var() function.

Can CSS variables store colors?

Yes. Colors are one of the most common uses.

Can CSS variables store numbers?

Yes. They can store numbers and many other CSS value forms.

Can CSS variables store units?

Yes. They can store values such as 20px, 2rem, or 50%.

Can CSS variables store gradients?

Yes. A custom property can store complete gradient values.

Can CSS variables store shadows?

Yes. Complete box-shadow values can be stored.

Can CSS variables be used with calc()?

Yes. Custom properties can be used inside calc() expressions.

Can media queries change CSS variables?

Yes. Media queries can redefine custom properties at different viewport conditions.

Can CSS variables create dark mode?

Yes. Theme classes or attributes can override a group of color variables.

Can JavaScript change CSS variables?

Yes. JavaScript can use style.setProperty() to update custom properties.

Can JavaScript read CSS variables?

Yes. Use getComputedStyle() with getPropertyValue().

Can JavaScript remove a variable?

Yes. removeProperty() can remove an inline custom property.

Are CSS variables the same as Sass variables?

No. CSS variables exist in the browser and participate in inheritance, while Sass variables are generally resolved during compilation.

Can a child override a parent variable?

Yes. A child or descendant scope can define its own value.

Can one variable use another variable?

Yes. A custom property value can reference another custom property.

Can variables be animated?

Some custom properties can participate in animation depending on how they are used, and registered custom properties can provide more explicit typing and animation behavior.

Should every CSS value become a variable?

No. Variables are most useful for reused, shared, configurable, themed, or dynamic values.

What is a design token?

A design token is a named reusable design decision such as a color, spacing value, font size, radius, or shadow.

Why are CSS variables useful for components?

They allow component appearance to be customized without duplicating the entire component stylesheet.

Do CSS variables follow the cascade?

Yes. Their values are affected by inheritance, specificity, and source order.

What happens if a variable does not exist?

A fallback can be used. Without a usable variable or fallback, the declaration can become invalid.

Is this the final CSS lesson?

Yes. This lesson completes the CSS course, covering the major foundations from CSS syntax and selectors through layouts, responsive design, animations, and reusable custom properties.

Key Takeaways

  • CSS Variables are officially called Custom Properties.
  • Custom property names begin with two hyphens.
  • The var() function reads a custom property value.
  • The :root selector is commonly used for global variables.
  • Variables can also be defined locally inside components.
  • Custom properties normally inherit from parent elements.
  • Variables can be overridden in smaller scopes.
  • The var() function can provide fallback values.
  • Variables can store colors, spacing, typography, borders, shadows, gradients, and other values.
  • Design tokens represent reusable design decisions.
  • CSS variables can be used inside calc().
  • Media queries can redefine variables.
  • Variables are useful for responsive values.
  • Theme systems can override groups of variables.
  • Components can expose variables for customization.
  • JavaScript can change CSS variables with setProperty().
  • JavaScript can read variables with getPropertyValue().
  • CSS variables exist at runtime in the browser.
  • CSS custom properties follow the normal cascade and inheritance.
  • Variables reduce duplication and improve maintainability.
  • CSS variables are one of the most powerful tools for modern design systems and dynamic interfaces.

Summary

CSS Variables allow reusable values to be stored as custom properties and accessed with the var() function.

Custom property names begin with two hyphens, such as --primary-color.

The :root selector is commonly used for globally shared variables.

Variables can also be defined locally on components and inherited by their descendants.

Custom properties can be overridden in smaller scopes, making them useful for component variants and themes.

The var() function can provide fallback values when a custom property is unavailable.

Variables can store reusable colors, spacing values, typography, borders, shadows, gradients, transitions, and many other CSS values.

Design tokens use meaningful variable names to represent reusable design decisions.

CSS variables can work with calc() to create reusable calculations.

Media queries can redefine variables to create responsive spacing, typography, and layouts.

Theme systems can change a small set of variables to update the appearance of an entire interface.

Reusable components can expose custom properties that act as a simple styling API.

JavaScript can read, update, and remove CSS custom properties while the application is running.

CSS variables follow the normal CSS cascade and inheritance system.

With CSS Variables complete, you have now finished all 24 lessons of the CSS course, from fundamental syntax and selectors to Flexbox, Grid, animations, responsive design, and dynamic design systems.