CSS Variables

Variables in CSS, officially known as CSS Custom Properties, are a game-changer for modern web design. In the past, developers had to rely on preprocessors like Sass or Less to use variables, but now they are built directly into the browser. They allow you to store specific values like colors, font sizes, or spacing in one place and reuse them throughout your entire stylesheet. This makes your code much cleaner, easier to read, and significantly faster to update when a design change is requested.

Developer Tip: Think of CSS variables as "single sources of truth." Instead of hunting through 2,000 lines of CSS to change a hex code, you change it once at the top, and the whole site updates instantly.

Basic Syntax

CSS variables follow a simple two-step process: declaration and usage. You define them using a double dash (--) prefix, and you access them using the var() function.

/* 1. Declaration */
:root {
    --primary-color: #007bff; 
    --main-border-radius: 8px;
}

/* 2. Usage */
.button {
    background-color: var(--primary-color);
    border-radius: var(--main-border-radius);
}

In this example:

  • :root: This is a CSS pseudo-class that matches the highest-level element in the document (usually the <html> tag). Declaring variables here makes them global, meaning they can be used anywhere in your CSS.
  • --primary-color: This is the variable name. It must start with two dashes.
  • var(): This function tells the browser to go find the value stored in that variable name and plug it in.
Best Practice: Always name your variables based on their intent rather than their value. For example, use --accent-color instead of --bright-red. If you decide to change that red to blue later, the name --accent-color still makes sense.

Using Variables

You aren't limited to just colors. CSS variables can hold almost any CSS value: pixels, percentages, font stacks, or even complex box-shadow strings.

:root {
    --standard-padding: 1.5rem;
    --header-font: 'Inter', sans-serif;
    --card-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
}

.card {
    padding: var(--standard-padding);
    font-family: var(--header-font);
    box-shadow: var(--card-shadow);
}
Watch Out: CSS variables are case-sensitive. --Main-Color and --main-color will be treated as two completely different variables.

Modifying Variables

One of the most powerful features of CSS variables is that they can be updated dynamically. This is incredibly useful for responsive design or user-controlled themes.

:root {
    --container-width: 1200px;
}

/* Update the variable for smaller screens */
@media (max-width: 768px) {
    :root {
        --container-width: 100%;
    }
}

.container {
    width: var(--container-width);
    margin: 0 auto;
}

By changing the variable inside a media query, any element using --container-width automatically adjusts without you having to write new rules for every single class.

Cascading and Inheritance

Just like standard CSS properties, variables "cascade." This means a variable defined inside a specific class will override a global variable for that element and its children.

:root {
    --text-color: black;
}

.dark-section {
    /* This only changes the value for .dark-section and its children */
    --text-color: white; 
    background-color: #333;
}

.dark-section p {
    color: var(--text-color); /* This will be white */
}
Common Mistake: Beginners often try to use variables for property names, like var(--side): 10px;. This will not work. Variables can only be used as values.

Fallback Values

Sometimes a variable might not be defined (for example, if a component is moved to a different project). You can provide a "fallback" value as a second argument inside the var() function.

.button {
    /* If --btn-color is missing, use 'blue' as a backup */
    background-color: var(--btn-color, blue);
}

Example Usage: Dark Mode Toggle

Here is a real-world example of how variables make "Dark Mode" implementation simple. Instead of rewriting every color rule, you simply swap the variable values.

/* Default Light Theme */
:root {
    --bg-color: #ffffff;
    --text-color: #222222;
    --link-color: #0044cc;
}

/* Dark Theme overrides */
[data-theme="dark"] {
    --bg-color: #1a1a1a;
    --text-color: #f0f0f0;
    --link-color: #66b3ff;
}

body {
    background-color: var(--bg-color);
    color: var(--text-color);
    transition: background-color 0.3s ease; /* Smooth transition! */
}

a {
    color: var(--link-color);
}

Benefits of Using Variables

  • Reusable Code: Stop repeating hex codes. Define them once and reuse them thousands of times.
  • Easy Maintenance: When your brand color changes from blue to purple, you only need to edit one line of code.
  • Dynamic Changes: You can change CSS variables using JavaScript (element.style.setProperty('--var', 'value')), enabling features like live theme customizers.
  • Readability: var(--brand-primary) is much easier to understand for a human developer than #3a5a40.

Browser Support

CSS variables are supported in all modern browsers (Chrome, Firefox, Safari, Edge). They have been standard since roughly 2017. While legacy browsers like Internet Explorer 11 do not support them, most modern web development projects no longer require IE11 compatibility. If you must support IE11, you may need a PostCSS plugin to compile them away.

By moving your hard-coded values into CSS variables, you're not just writing styles you're building a design system that can grow and change with your project.