CSS Variables let you reuse CSS values via custom properties. Learn the syntax, browser support across Chrome 49+, Firefox 31+, Safari 9.1+, and IE fallbacks.

Prince Dewani
May 6, 2026
CSS Variables are a W3C feature that lets you store values like colors, sizes, or fonts in custom properties prefixed with two dashes and reuse them through the var() function. They work in Chrome 49+, Edge 16+, Firefox 31+, Safari 9.1+ on macOS and iOS, Opera 36+, and Samsung Internet 5+, while Internet Explorer 5.5 to 11 never added support.
This guide covers what CSS Variables are, browser support, the syntax, fallbacks, how to check support, and known issues.
CSS Variables are a W3C CSS Custom Properties for Cascading Variables Module Level 1 feature. They define reusable custom properties on any selector, prefixed with two dashes such as --main-color: blue, and read them back through the var() function. Variables cascade and inherit like any other CSS property.
CSS Variables work in every modern desktop and mobile browser, with Chrome shipping support in Chrome 49, Firefox in Firefox 31, Safari in Safari 9.1, and Edge in Edge 16. Internet Explorer 5.5 to 11 never added support, and Opera Mini still does not support custom properties.
Chrome supports CSS Variables from Chrome 49 on Windows, macOS, Linux, ChromeOS, and Android. Chrome 48 had CSS Variables disabled by default behind the Experimental Web Platform features flag, and Chrome 4 to 47 did not support custom properties at all. Chrome for Android picks up the same baseline from Chrome 49 on Android.
Microsoft Edge supports CSS Variables from Edge 16 on Windows 10, with Edge 15 offering partial support that ignored a handful of edge cases around invalid values. Modern Chromium-based Edge 79+ inherits full Chromium support across Windows, macOS, and Linux. Legacy Edge 12 to 14 did not support custom properties.
Firefox supports CSS Variables from Firefox 31 on Windows, macOS, Linux, and Android, and Firefox for Android picks up the same baseline. Firefox 1 to 30 did not implement custom properties or the var() function. Firefox shipped support earliest among the major browsers, so Firefox-only test runs catch regressions before other engines.
Safari supports CSS Variables from Safari 9.1 on macOS El Capitan, and from Safari 10 on iOS for iPhone and iPad. Safari 9.3 on iOS offered partial support before Safari 10 shipped full coverage. Safari 3.1 to 9 on macOS and iOS 3 to 9.2 did not support custom properties, and several calc() interactions were patched up through Safari 14.
Opera supports CSS Variables from Opera 36 on desktop, with Opera 35 offering it disabled by default behind the Chromium experimental flag. Opera Mobile supports custom properties from Opera Mobile 80 on Android. Opera Mini does not support CSS Variables, since the Presto-based proxy renderer pre-processes pages on Opera servers and strips var() calls.
Samsung Internet supports CSS Variables from Samsung Internet 5 on Galaxy phones and tablets. Older Samsung Internet 4 builds did not support custom properties, so visitors on stale Galaxy devices fall back to whatever the cascade resolves to before the var() declaration.
Chrome for Android supports CSS Variables from Chrome for Android 49 on Android 5 and later, matching desktop Chrome. The legacy stock Android Browser, frozen at WebKit 4.4, does not support custom properties. Firefox for Android supports them from Firefox for Android 31, so most modern Android phones render CSS Variables natively.
Internet Explorer does not support CSS Variables in any version. IE 5.5 to 11 predate the W3C Custom Properties for Cascading Variables Module spec, and Microsoft has retired Internet Explorer in favor of Chromium Edge. Sites that still serve IE traffic must compile variables to literal values with PostCSS or Sass before deploying.
Note: CSS Variables fail silently on Internet Explorer and older Safari, iOS, and Android WebView builds. Test them on real browsers and OS with TestMu AI. Try TestMu AI free!
A CSS Variable is declared by writing a custom property prefixed with two dashes inside any selector, then read with the var() function. The browser resolves the value at runtime and inherits it down the DOM tree, so a value declared on :root is available to every descendant.
The example below declares three variables on :root, reads them inside .button, overrides one on .card.dark, and uses a variable inside calc().
/* Declare CSS Variables on :root for global scope */
:root {
--main-color: #2962ff;
--spacing: 1.5rem;
--base-font: "Inter", system-ui, sans-serif;
}
/* Read them with var() and provide a fallback value */
.button {
color: var(--main-color);
padding: var(--spacing, 1rem);
font-family: var(--base-font);
}
/* Override the variable on a child element */
.card.dark {
--main-color: #ffffff;
}
/* Variables resolve through calc() and at-rules */
.grid {
width: calc(100% - var(--spacing) * 2);
}A few rules apply across every browser that ships CSS Variables:
Pair every var() reference with either a literal fallback inside the function or a duplicate property declared above the var() line. The duplicate pattern is the only one that rescues Internet Explorer, since IE drops every declaration that contains a var() call, including the literal inside the function call itself.
Run a quick CSS.supports probe in DevTools, or wrap a block in @supports inside your stylesheet. Both paths give a one-line yes or no without changing visible styling.
The console snippet below packages the probe and prints a one-line yes or no, then reads and writes a variable from JavaScript:
// Run in the browser DevTools Console
const ok = window.CSS && window.CSS.supports("(--probe: 0)");
console.log("CSS Variables:", ok ? "yes" : "no");
// Read or write a variable from JavaScript
const root = document.documentElement;
const main = getComputedStyle(root).getPropertyValue("--main-color");
console.log("Current --main-color:", main.trim());
root.style.setProperty("--main-color", "#ff5722");If the probe returns false, fall back to a precompiled flat stylesheet built with PostCSS, Sass, or Less so the page still renders correctly.
CSS Variables are well established now, but a few rough edges still trip developers up. The biggest hits are the no-fallback drop in Internet Explorer, animation limits without @property registration, and quirks around media query feature values.
In my experience, the most surprising failure happens with Internet Explorer 11. A page renders in what looks like default browser styling because IE drops every declaration that contains a var() call, including the literal fallback inside the function. The fix is to declare a duplicate property above the var() line so IE picks up the duplicate while modern browsers apply the variable on the line below.
All CSS Variables version numbers and platform notes in this guide come from these primary sources:
Did you find this page helpful?
More Related Hubs
TestMu AI forEnterprise
Get access to solutions built on Enterprise
grade security, privacy, & compliance