5

Is there any way to detect whether a browser supports CSS custom properties (eg. color: var(--primary))?

I need to write a script that behaves slightly differently in browsers that don't support custom properties, but I can't find any documented Modernizr tests, nor any information about the Javascript interface for accessing custom properties.

Would be grateful for any suggestions!

BoltClock
  • 700,868
  • 160
  • 1,392
  • 1,356
Nick F
  • 9,781
  • 7
  • 75
  • 90
  • No wonder this question seemed so familiar. A pox on me for answering a duplicate? – BoltClock Jun 24 '16 at 11:29
  • Ah, I did search for duplicates, but I was looking for "custom properties" (the official name, I believe), not "CSS variables". – Nick F Jun 24 '16 at 11:43
  • Yeah - people call them CSS variables because it's more relatable, and partially also because the module is called "Custom Properties for Cascading Variables", which they kind of are. – BoltClock Jun 24 '16 at 11:44
  • Oh, yeah, it totally makes sense to refer to them as CSS variables. I do myself. Having an alternative name in common use just makes searching for info a bit more difficult! – Nick F Jun 24 '16 at 13:56

2 Answers2

17

You can reliably use CSS.supports() in JavaScript or @supports in CSS to detect support for custom properties. Every version of every browser that supports custom properties also supports this method of feature detection.

if (window.CSS && CSS.supports('color', 'var(--primary)')) {
  document.body.innerHTML = 'Supported';
}
@supports (color: var(--primary)) {
  body {
    background-color: green;
  }
}

Notice that this does not require you to declare the --primary custom property, as by definition every property whose name begins with -- is considered valid for the purposes of parsing property declarations.

BoltClock
  • 700,868
  • 160
  • 1,392
  • 1,356
  • How wonderfully direct! – T.J. Crowder Jun 24 '16 at 11:19
  • You may want to check if CSS.supports is defined before calling. – jcubic Jun 24 '16 at 11:23
  • @jcubic: Thanks, fixed. – BoltClock Jun 24 '16 at 11:29
  • Just in case anyone else wonders if `CSS` can be defined without `CSS.supports` being defined (thus, do you need to check for `CSS.supports` before calling it, or is checking for `window.CSS` sufficient?): the `CSS` global was introduced with `supports` being its initial rationale; all browsers with a `CSS` global have `CSS.supports`. – Chris Morgan Dec 12 '18 at 22:50
1

I'll leave this as an example of how to approach this sort of thing when you don't have an alternative, but BoltClock's answer is the way to go in this case.


I expect you could define one and then check whether its value comes through to getComputedStyle. For instance, this shows Supports custom props? true on Chrome (which supports custom CSS properties) but Supports custom props? false on IE11 (which doesn't):

function areCSSVarsSupported() {
  var d = document.createElement('div');
  d.id = "test";
  document.body.appendChild(d);
  var pos = getComputedStyle(d).position;
  document.body.removeChild(d);
  return pos === "fixed";
}
console.log("Supports custom props? " + areCSSVarsSupported());
:root{
  --test-vars: fixed;
}

#test {
  position: var(--test-vars);
}
Community
  • 1
  • 1
T.J. Crowder
  • 1,031,962
  • 187
  • 1,923
  • 1,875