1. Introduction
CSS stylesheets are parsed into abstract UA-internal data structures, the internal representations of CSS, which various specification algorithms manipulate.
Internal representations can’t be directly manipulated, as they are implementation-dependent; UAs have to agree on how to interpret the internal representations, but the representations themselves are purposely left undefined so that UAs can store and manipulate CSS in whatever way is most efficient for them.
Previously, the only way to read or write to the internal representations was via strings—stylesheets or the CSSOM allowed authors to send strings to the UA, which were parsed into internal representations, and the CSSOM allowed authors to request that the UA serialize their internal representations back into strings.
This specification introduces a new way to interact with internal representations, by representing them with specialized JS objects that can be manipulated and understood more easily and more reliably than string parsing/concatenation. This new approach is both easier for authors (for example, numeric values are reflected with actual JS numbers, and have unit-aware mathematical operations defined for them) and in many cases are more performant, as values can be directly manipulated and then cheaply translated back into internal representations without having to build and then parse strings of CSS.
2. CSSStyleValue
objects
[Exposed =(Window ,Worker ,PaintWorklet ,LayoutWorklet )]interface {
CSSStyleValue stringifier ; [Exposed =Window ]static CSSStyleValue parse (USVString ,
property USVString ); [
cssText Exposed =Window ]static sequence <CSSStyleValue >parseAll (USVString ,
property USVString ); };
cssText
CSSStyleValue
objects are the base class of all CSS values accessible via the Typed OM API.
The stringification behavior of CSSStyleValue
objects
is defined in § 6 CSSStyleValue Serialization.
The parse(property, cssText)
method,
when invoked,
must parse a CSSStyleValue with property property, cssText cssText, and parseMultiple set to false,
and return the result.
The parseAll(property, cssText)
method,
when invoked,
must parse a CSSStyleValue with property property, cssText cssText, and parseMultiple set to true,
and return the result.
-
If property is not a custom property name string, set property to property ASCII lowercased.
-
If property is not a valid CSS property, throw a
TypeError
. -
Attempt to parse cssText according to property’s grammar. If this fails, throw a
TypeError
. Otherwise, let whole value be the parsed result.The behavior of custom properties are different when modified via JavaScript than when defined in style sheets.When a custom property is defined with an invalid syntax in a style sheet, then the value is recorded as "unset", to avoid having to reparse every style sheet when a custom property is registered.
Conversely, when a custom property is modified via the JavaScript API, any parse errors are propagated to the progamming environment via a
TypeError
. This allows more immediate feedback of errors to developers. -
Subdivide into iterations whole value, according to property, and let values be the result.
-
For each value in values, replace it with the result of reifying value for property.
-
If parseMultiple is false, return values[0]. Otherwise, return values.
-
If property is a single-valued property, return a list containing whole value.
-
Otherwise, divide whole value into individual iterations, as appropriate for property, and return a list containing the iterations in order.
<foo>#
term in the grammar),
but some legacy properties (such as counter-reset)
don’t separate their iterations with commas.
It’s expected to be rigorously defined in the future, but at the moment is explicitly a "you know what we mean" thing.
2.1. Direct CSSStyleValue
Objects
Values that can’t yet be directly supported by a more specialized CSSStyleValue
subclass
are instead represented as CSSStyleValue
objects.
Each CSSStyleValue
object is associated with a particular CSS property,
via its [[associatedProperty]]
internal slot,
and a particular, immutable, internal representation.
These objects are said to "represent" the particular internal representation they were reified from,
such that if they are set back into a stylesheet for the same property,
they reproduce an equivalent internal representation.
These CSSStyleValue
objects are only considered valid for the property that they were parsed for.
This is enforced by CSSStyleValue
objects having a [[associatedProperty]]
internal slot,
which is either null
(the default)
or a string specifying a property name.
Note: This slot is checked by StylePropertyMap
.set()
/append()
3. The StylePropertyMap
[Exposed =(Window ,Worker ,PaintWorklet ,LayoutWorklet )]interface {
StylePropertyMapReadOnly iterable <USVString ,sequence <CSSStyleValue >>; (undefined or CSSStyleValue )get (USVString );
property sequence <CSSStyleValue >getAll (USVString );
property boolean has (USVString );
property readonly attribute unsigned long size ; }; [Exposed =Window ]interface :
StylePropertyMap StylePropertyMapReadOnly {undefined set (USVString , (
property CSSStyleValue or USVString )...);
values undefined append (USVString , (
property CSSStyleValue or USVString )...);
values undefined delete (USVString );
property undefined clear (); };