Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Listen to CSS variable change?

Is it possible to use a callback to listen to CSS variable changes? something like this:

documentElement.addListener('css-var-main-background-color', () => {
  console.log('Value changed');
});
like image 709
Hammerhead Avatar asked Sep 14 '19 10:09

Hammerhead


People also ask

Can CSS variables be changed?

CSS variables have access to the DOM, which means that you can change them with JavaScript.

What does VAR () do in CSS?

The var() CSS function can be used to insert the value of a custom property (sometimes called a "CSS variable") instead of any part of a value of another property.

Are CSS variables support?

CSS variables are currently supported for 93 percent of users globally. If a browser doesn't support CSS variables, it also doesn't understand the var() function, and doesn't know what its second argument means. Instead, we need to use the cascade, as we do for every new CSS feature.


1 Answers

Variables defined in style attribute

If you have full control over the code and can set CSS variables via the style attribute on a DOM element rather than using a stylesheet, you can use MutationObserver to detect changes on that element's style attribute and thus detect changes to the variable.

The variables must be set like this:

document.documentElement.style.setProperty('--var1', '1');

and NOT like this:

:root {
--var1: 1;
}

Then you can monitor changes to the style attribute of the target element.

let value = '1';

const styleObserver = new MutationObserver((mutations) => {
  const currentValue = mutations[0].target.style.getPropertyValue('--var1');

  if (currentValue !== value) {
    // the variable has changed
    value = currentValue;
  }
});

styleObserver.observe(document.documentElement, {
  attributes: true,
  attributeFilter: ['style'],
});

The above example is for the html element which is usually where you put global variables, but it can work with any other element.

Variables defined in a stylesheet

It is possible if you are willing to define the stylesheet in a specific way:

  • Variables must be defined in a <style></style> element
  • The style element should contain only the variables you want to watch to keep it as specific as possible and not trigger the observer when unrelated properties change

Then you can use MutationObserver to watch changes to the style element and parse its contents to detect which variables have changed.

like image 50
Maciej Krawczyk Avatar answered Oct 20 '22 17:10

Maciej Krawczyk