This specification extends and overrides the DOM4 specification [DOM4] with additional support to detect CSS style changes.

Introduction

This draft proposes an extension to the Mutation Observers mechanism to provide means to track changes in the computed style of DOM elements. To this end, it extends the MutationObserverInit interface and the MutationRecord interface.

This extension allows scripts to efficently react on style changes, which may be important for any functionality incooperating style.

For instance, oberserving style changes is of importance applications that use polyfills that need to consider the style when rendering declarative content.

It is also important for applications and frameworks that use Custom CSS Properties [CSS-Variables-1] and have to react on changes to the computed value of such a property.

On important application of Custom CSS Properties is Declarative 3D, where CSS is used to define geometry transformations, visibility and material, light and camera models.

Terminology

Conformance requirements

Additions to Mutation Observers

Additions to the MutationObserverInit dictionary

boolean cssProperties
Set to true if mutations to target's CSS properties are to be observed.
boolean ccsCustomPropertiesOnly
Set to true if cssProperties is set to true and only custom CSS properties are to be observed.
DOMString[] cssPropertyFilter
Set to a list of CSS property names if not all CSS property mutations need to be observed.
boolean cssPropertyOldValue
Set to true if cssProperties is set to true and target's cssProperty value before the mutation needs to be recorded.

Changes in behavior of MutiationObserver

The observe(target, options) method of MutiationObserver must run these steps:

  1. Run these substeps, with options as the context object:
    1. If neither childList, attributes, cssProperties, nor characterData is true, throw a "SyntaxError" and terminate these steps.
    2. If attributeOldValue is true and attributes is not true, throw a "SyntaxError" and terminate these steps.
    3. If attributeFilter is a non-empty array and attributes is not true, throw a "SyntaxError" and terminate these steps.
    4. If characterDataOldValue is true and characterData is not true, throw a "SyntaxError" and terminate these steps.
    5. If cssPropertyOldValue is true and cssProperties is not true, throw a "SyntaxError" and terminate these steps.
    6. If cssPropertyFilter is a non-empty array and cssProperties is not true, throw a "SyntaxError" and terminate these steps.
  2. If target's list of registered observers already includes a registered observer associated with the context object, replace that registered observer's options with options.
  3. Otherwise, add a new registered observer to target's list of registered observers with the context object as the observer and options as the options, and add target to context object's list of nodes on which it is registered.

Additions to the MutationRecord interface

We extend MutationRecord interface with cssPropertyName and pseudoElem attributes. Existing type attribute returns "cssProperties" value when CSS properties of the tree of nodes were mutated.

readonly attribute DOMString type
Additionally to the "attributes", "characterData", and "childList" values we return "cssProperties" if it was a mutation to the CSS properties of the tree of nodes.
readonly attribute DOMString? cssPropertyName
Returns the name of the changed CSS property, or null otherwise.
readonly attribute DOMString? pseudoElem
Returns the pseudoElement definition of which the CSS property changed, or null otherwise.

Queuing of records for css property changes

To queue an "cssProperties" record with target target, pseudo element pseudoElem css property name propertyName, and oldValue oldValue, run these steps:

  1. Let record be a new MutationRecord object with its type set to "cssProperties", target set to target, pseudoElem set to pseudoElem, and cssPropertyName set to propertyName.
  2. Let recordWithOldValue be a copy of record with its oldValue set to oldValue.
  3. For each registered observer observer (with observer's options as options) in target's list of registered observers, run these substeps:
    1. If options's cssProperties is not true, terminate these substeps (and run them for the next registered observer).
    2. If options's attributeFilter is non-empty, and name is not in it, terminate these substeps (and run them for the next registered observer).
    3. If options's cssPropertyOldValue is true, append recordWithOldValue to observer's observer record queue.
    4. Otherwise, append record to observer's observer record queue.
  4. For each ancestor ancestor of target, and for each registered observer observer (with observer's options as options) in ancestor's list of registered observers, run these substeps:
    1. If options's subtree is not true, terminate these substeps (and run them for the next registered observer).
    2. If options's cssProperties is not true, terminate these substeps (and run them for the next registered observer).
    3. If options's attributeFilter is non-empty, and name is not in it, terminate these substeps (and run them for the next registered observer).
    4. If options's cssPropertyOldValue is true, append recordWithOldValue to observer's observer record queue.
    5. Otherwise, append record to observer's observer record queue.

A. References

A.1 Normative references

[DOM4]
Anne van Kesteren; et al. DOM4.. W3C Working Draft. URL:http://www.w3.org/TR/dom/
[CSS21]
Bert Bos; et al. Cascading Style Sheets Level 2 Revision 1 (CSS 2.1) Specification.. W3C Recommendation. URL: http://www.w3.org/TR/CSS21/
[CSS-VARIABLES-1]
Tab Atkins Jr. CSS Custom Properties for Cascading Variables Module Level 1 W3C Working Draft. URL: http://www.w3.org/TR/css-variables-1/
[HTML5]
Ian Hickson; David Hyatt. HTML5. URL: http://dev.w3.org/html5/spec/
[RFC2119]
S. Bradner. Key words for use in RFCs to Indicate Requirement Levels. March 1997. Internet RFC 2119. URL: http://www.ietf.org/rfc/rfc2119.txt
[WEBIDL]
Cameron McCormack. Web IDL. 19 December 2008. W3C Working Draft. (Work in progress.) URL: http://www.w3.org/TR/2008/WD-WebIDL-20081219

A.2 Informative references

Acknowledgements

Many thanks to Robin Berjon for making our lives so much easier with his cool tool.