HTML, CSS & the Browser

CSS Variable

Definition

Custom properties are ordinary CSS declarations whose names begin with two hyphens. They are usually declared on :root, which is the html element, so they are available everywhere: :root { --space: 16px; --text: #111; }. Any property can then take var(--space) as its value, with an optional fallback as a second argument — var(--space, 12px) is used if the variable is not defined. They inherit like any other property, so redeclaring one on a container changes it for that container and everything inside it, and nothing else. Unlike variables in a preprocessor such as Sass, these are live at runtime: the browser resolves them each time, and a script can change one with setProperty, repainting everything that depends on it.

Why It Matters

One declaration changing forty places is the obvious win, but the useful part is the switching. A theme is a set of variables; changing a theme is redeclaring that set under a different condition, which is how dark mode gets done in a handful of lines rather than a duplicated stylesheet. The same applies to a spacing scale or a type ramp — tighten --space once and the whole page tightens consistently. They are also the only sensible way to hand a value from a script to CSS: set --progress: 62% on an element and let the stylesheet decide what to do with it, instead of writing inline styles from JavaScript.

How It Works

A custom property is resolved at use, not at declaration, and it resolves against the element it is used on. That is what makes scoping work: declare --accent on .panel and every var(--accent) inside that panel picks up the new value through inheritance, while the rest of the page keeps the root value. If a variable is undefined and has no fallback, the declaration using it becomes invalid at computed-value time and the property falls back to its inherited or initial value — often not what the author expected, which is why the two-argument form of var() is worth the extra characters. Names are case-sensitive: --mainColor and --maincolor are two different properties. In the styles panel of developer tools, a var() value is shown with the resolved value beside it, so a variable that never got set is visible at a glance.

Real-World Example

A studio publishes brand guidelines at northlight-brand.99helpers.site with eight colours, three spacing steps and two typefaces defined as custom properties on :root. When the accent colour is revised, one line changes and the swatches, headings, buttons and link colours all follow. A dark theme is then added as fourteen lines redeclaring those same names inside a prefers-color-scheme block, with no rules duplicated.

Common Mistakes

  • Using a variable that was never declared and leaving out the fallback — the whole declaration is discarded, so the element quietly reverts to its inherited value rather than showing an error
  • Declaring the variable on a child and using it on a parent — custom properties inherit downwards only, so the parent never sees it
  • Expecting them to work like Sass variables inside a media query condition — a custom property can be the value of a property, but not part of the query condition itself

Related Terms

Put a file online in seconds

Drop in a document, an image, a page or a whole static website and share the link — free, with no build step and no server to set up.

Host a file free →