MutationObserver for CSS
While MutationObserver
can track DOM changes, it cannot be used to track style changes. This library plugs that gap and allows you to set up an observer tracking changes in values of CSS Properties.
The main use case for this library is to track changes to CSS Custom Properties (aka CSS Variables) but it can be used for other properties as well.
npm install @bramus/style-observer
// Vanilla JS (CommonJS)
const CSSStyleObserver = require('@bramus/style-observer');
// Vanilla JS (ES6)
import CSSStyleObserver from '@bramus/style-observer';
// TypeScript
import CSSStyleObserver from '@bramus/style-observer/src/index.ts'
const cssStyleObserver = new CSSStyleObserver(
/* CSS Properties to observe */
['--variable1', '--variable2', 'display', 'border-width'],
/* This is called whenever there are changes */
(values) => {
console.log(values['--variable1'], values['--variable2'], values['display']);
}
);
cssStyleObserver.attach(document.body); /* Attach observer to `document.body` */
//...
cssStyleObserver.detach(); /* Detach observer */
Below is a list of commands you will probably find useful.
Runs the project in development/watch mode, starts HTTP server and navigates to http://localhost:8080/demo
Runs the project in development/watch mode. Your project will be rebuilt upon changes.
Bundles the package to the dist
folder.
The package is optimized and bundled with Rollup into multiple formats (CommonJS, UMD, and ES Module).
The requirement for this library to work is support for CSS Transitions.
However, to also support properties that animate discretely – such as Custom Properties but also properties like display
– the browser must support transition-behavior: allow-discrete
.
In practice, this translates to the following list of browsers:
- Safari 18
- Firefox 129
- Google Chrome 117
Note: Google Chrome does not play nice with Custom Properties because of https://crbug.com/360159391
This library doesn’t use requestAnimationFrame
but responds to transition events. Therefore it doesn’t put a recurring and constant strain on the main thread.
The original css-variable-observer
library that coined this approach only works with custom properties and numeric values. This library can work with any property having any value.
The properties that are being tracked are set to a very short transition time. If you relied on transitions for those properties, that is now no longer possible.
You can work around this by putting a value into a custom property that you track and then use that custom property in a regular property. The regular property can have any transition you want.
Also note that changing the value transition
property yourself will make this library no longer work.
This library builds upon the css-variable-observer
project by Artem Godin. The suggestion to leverage transition-behavior: allow-discrete
was done by Jake Archibald in w3c/csswg-drafts#8982.