1. Introduction
Converting CSSOM value strings into meaningfully typed JavaScript representations and back can incur a significant performance overhead. This specification exposes CSS values as typed JavaScript objects to facilitate their performant manipulation.
The API exposed by this specification is designed for performance rather than ergonomics. Some particular considerations:
-
retrieved JavaScript representations of CSS values are not mutable - instead updates must explicitly be set using the API.
-
objects are organized for consistency rather than ease of access. For example, even though lengths are often numeric pixel values, a specified
CSSLengthValue
can’t be treated as a number without first explicitly casting it to aCSSSimpleLength
, as calc expressions and keywords are also valid lengths.
2. CSSStyleValue
objects
interface CSSStyleValue { readonly attribute DOMString cssText; static (CSSStyleValue or sequence<CSSStyleValue>)? parse(DOMString property, DOMString cssText); };
CSSStyleValue
objects are the base class of all CSS Values accessible via the Typed OM API.
Values that can’t yet be directly supported by a CSSStyleValue
subclass
are also represented as CSSStyleValue
objects.
The cssText attribute,
on getting,
returns a normalized representation
(see §5 CSSStyleValue normalization)
of the value the CSSStyleValue
object represents.
-
Attempt to parse property as an <ident>. If this fails, throw a
SyntaxError
and exit this algorithm. Otherwise, let property be the parsed result. If property does not start with two dashes (U+002D HYPHEN), let property be property converted to ASCII lowercase. -
If property is not a supported property name, throw a
TypeError
and exit this algorithm. -
Attempt to parse cssText according to property’s grammar. If this fails, throw a
SyntaxError
and exit this algorithm. Otherwise, let value be the parsed result. -
If property is a list-valued property, subdivide value into a list of
CSSStyleValue
objects, each representing one list-valued property iteration, and let value be the result. -
Return a
CSSStyleValue
representing value.
3. The StylePropertyMap
interface StylePropertyMapReadOnly { CSSStyleValue? get(DOMString property); sequence<CSSStyleValue> getAll(DOMString property); boolean has(DOMString property); iterable<DOMString, (CSSStyleValue or sequence<CSSStyleValue>)>; sequence<DOMString> getProperties(); stringifier; }; interface StylePropertyMap : StylePropertyMapReadOnly { void append(DOMString property, (CSSStyleValue or DOMString)... values); void delete(DOMString property); void set(DOMString property, (CSSStyleValue or DOMString)... values); };
A StylePropertyMapReadOnly
object has an associated property model,
which is a list of property - sequence<CSSStyleValue
> pairs. This list
is initialized differently depending on where the CSSStyleValue
is used
(see §3.1 Computed StylePropertyMapReadOnly objects, §3.2 Specified StylePropertyMap objects, and §3.3 Inline StylePropertyMap objects).
CSSStyleValue
s associated with a property do
not represent multiple successive definitions of that property’s value.
Instead, sequences represent values associated with list-valued properties.
This approach allows single-valued properties to become list-valued in the
future without breaking code that relies on calling get()
and/or set()
for those properties.
-
If property does not start with two dashes (U+002D HYPHEN), let property be property converted to ASCII lowercase.
-
If property is not a supported property name, throw a
TypeError
and exit this algorithm. -
If property is not a list-valued property, throw a
TypeError
and exit this algorithm. -
If
StylePropertyMap
’s property model contains an entry for property, let entry be that entry. Otherwise, create a new entry for property with an empty list, add it to the property model, and let entry be the newly-created entry. -
Let values to append be the empty list.
-
For each value in values:
-
If value is a
CSSStyleValue
, -
If value does not match the grammar of a list-valued property iteration of property, throw a
TypeError
and exit this algorithm. Otherwise, append value to the end of values to append. -
If value is a
DOMString
, -
Parse a CSSStyleValue with property property and value value. If the result is null, throw a
TypeError
and exit this algorithm. Otherwise, append each list-valued property iteration in the result to the end of values to append.
-
-
Append values to append to the end of entry’s list.
The getProperties() method returns all of the properties listed in the property model. This list of properties is sorted in the following manner:
-
normal properties are sorted alphabetically.
-
custom properties are sorted by increasing code point order.
-
custom properties are sorted after normal properties.
should refactor out value type-checking, as it’ll be needed by the rest of the setters too <https://github.com/w3c/css-houdini-drafts/issues/145>
need a robust description of what "a type that property can’t accept" means. <https://github.com/w3c/css-houdini-drafts/issues/147>
add detailed descriptions of the rest of the methods on StylePropertyMap
<https://github.com/w3c/css-houdini-drafts/issues/148>
describe that these are not live objects <https://github.com/w3c/css-houdini-drafts/issues/149>
3.1. Computed StylePropertyMapReadOnly
objects
partial interface Window { StylePropertyMapReadOnly getComputedStyleMap(Element element, optional DOMString? pseudoElt); };
Computed StylePropertyMap objects represent the computed style of an Element
or pseudo element, and are accessed by calling the getComputedStyleMap(Element, optional DOMString?)
method.
When constructed, the property model for computed StylePropertyMap objects is initialized to contain an entry for every valid CSS property supported by the User Agent.
Note: The StylePropertyMap returned by getComputedStyleMap represents computed style, not resolved style. In this regard it provides different values than those in objects returned by getComputedStyle.
3.2. Specified StylePropertyMap
objects
partial interface CSSStyleRule { [SameObject] readonly attribute StylePropertyMap styleMap; };
Specified StylePropertyMap objects represent style property-value pairs embedded
in a style rule, and are accessed via the styleMap attribute of CSSStyleRule
objects.
When constructed, the property model for specified StylePropertyMap objects is initialized to contain
an entry for each property that is paired with at least one valid value inside the CSSStyleRule
that the object represents. The value for a given property is
the last valid value provided by the CSSStyleRule
object.
3.3. Inline StylePropertyMap
objects
partial interface Element { [SameObject] readonly attribute StylePropertyMap styleMap; };
Inline StylePropertyMap objects represent inline style declarations attached
directly to Element
s. They are accessed via the styleMap attribute of Element
objects.
When constructed, the property model for inline StylePropertyMap objects is initialized to contain an entry for each property that is paired with at least one valid value in the string representing the style attribute for the Element that the object is associated with. The value for a given property is the last valid value provided in the string.
4. CSSStyleValue
subclasses
4.1. CSSUnparsedValue
objects
interface CSSUnparsedValue : CSSStyleValue { iterable<(DOMString or CSSVariableReferenceValue)>; }; interface CSSVariableReferenceValue { readonly attribute DOMString variable; readonly attribute CSSUnparsedValue fallback; };
CSSUnparsedValue
objects represent values that reference custom properties. They represent a list of string fragments and variable references.
4.2. CSSKeywordValue
objects
[Constructor(DOMString)] interface CSSKeywordValue : CSSStyleValue { readonly attribute DOMString keywordValue; };
CSSKeywordValue
objects represent CSSStyleValue
s that are keywords. The constructor for CSSKeywordValue
should check that they contain valid CSS, but they do not check whether the contained string is a valid
keyword for a particular property. Property setters are required to enforce keyword validity.
4.3. CSSNumberValue
objects
[Constructor(double), Constructor(DOMString cssText)] interface CSSNumberValue : CSSStyleValue { readonly attribute double value; };
CSSNumberValue
objects represent values for simple number-valued properties like z-index or opacity.
CSSNumberValue
objects are not range-restricted. Any valid number can be represented by a CSSNumberValue
,
and that value will not be clamped, rounded, or rejected when set on a specified StylePropertyMap or inline StylePropertyMap. Instead, clamping and/or rounding will occur during computation of style.
myElement.styleMap.set("opacity", new CSSNumberValue(3)); myElement.styleMap.set("z-index", new CSSNumberValue(15.4)); console.log(myElement.styleMap.get("opacity").value); // 3 console.log(myElement.styleMap.get("z-index").value); // 15.4 var computedStyle = getComputedStyleMap(myElement); var opacity = computedStyle.get("opacity"); var zIndex = computedStyle.get("z-index");
After execution, the value of opacity
is 1 (opacity is range-restricted),
and the value of zIndex
is 15 (z-index is rounded to an integer value).
4.4. CSSLengthValue
objects
enum LengthType { "px", "percent", "em", "ex", "ch", "rem", "vw", "vh", "vmin", "vmax", "cm", "mm", "q", "in", "pc", "pt" }; dictionary CSSLengthCalcDictionary { double px; double percent; double em; double ex; double ch; double rem; double vw; double vh; double vmin; double vmax; double cm; double mm; double q; double in; double pc; double pt; }; interface CSSLengthValue : CSSStyleValue { CSSLengthValue add(CSSLengthValue value); CSSLengthValue subtract(CSSLengthValue value); CSSLengthValue multiply(double value); CSSLengthValue divide(double value); static CSSLengthValue from(DOMString cssText); static CSSLengthValue from(double value, LengthType type); static CSSLengthValue from(optional CSSLengthCalcDictionary dictionary); }; [Constructor(DOMString cssText), Constructor(CSSLengthValue), Constructor(CSSLengthCalcDictionary) ] interface CSSCalcLength : CSSLengthValue { readonly attribute double? px; readonly attribute double? percent; readonly attribute double? em; readonly attribute double? ex; readonly attribute double? ch; readonly attribute double? rem; readonly attribute double? vw; readonly attribute double? vh; readonly attribute double? vmin; readonly attribute double? vmax; readonly attribute double? cm; readonly attribute double? mm; readonly attribute double? q; readonly attribute double? in; readonly attribute double? pc; readonly attribute double? pt; }; // lengths that are *just* keywords don’t become CSSSimpleLengths or CSSCalcLengths. // Instead they are represented as CSSKeywordValue objects. [Constructor(DOMString cssText), Constructor(CSSLengthValue), Constructor(double value, LengthType type)] interface CSSSimpleLength : CSSLengthValue { readonly attribute double value; readonly attribute LengthType type; };
CSSLengthValue
objects represent lengths:
-
CSSSimpleLength
objects represent lengths that contain a single unit type (for example "42px"). -
CSSCalcLength
objects represent lengths that contain multiple units (for example "calc(56em + 10%)").
CSSLengthValue
objects are not range-restricted. Any valid combination of primitive lengths can be represented by a CSSLengthValue
,
that value will be accepted unaltered when set on a specified StylePropertyMap or inline StylePropertyMap. Instead, clamping and/or rounding will occur during computation of style.
Note that lengths which incorporate variable references will instead be represented as CSSUnparsedValue
objects, and keywords as CSSKeywordValue
objects.
The following methods are defined for CSSLengthValue
objects:
-
add(CSSLengthValue value)
-
Adds the provided value to the length represented by the object, and returns the result as a new
CSSLengthValue
. This will construct aCSSSimpleLength
orCSSCalcLength
depending on whether the result can be expressed in terms of a single unit. -
subtract(CSSLengthValue value)
-
Subtracts the provided value from the length represented by the object, and returns the result as a new
CSSLengthValue
. This will construct aCSSSimpleLength
orCSSCalcLength
depending on whether the result can be expressed in terms of a single unit. -
multiply(double value)
-
Multiplies the length represented by the object by the provided value, and returns the result as a new
CSSLengthValue
. This will construct aCSSSimpleLength
if the object is aCSSSimpleLength
, or aCSSCalcLength
if the object is aCSSCalcLength
. -
divide(double value)
-
Divides the length represented by the object by the provided value, and returns the result as a new
CSSLengthValue
. This will construct aCSSSimpleLength
if the object is aCSSSimpleLength
, or aCSSCalcLength
if the object is aCSSCalcLength
. The function will throw a RangeError when the value given is 0. -
from(DOMString cssText)
-
Parses the provided cssText as a length value. Will return a
CSSSimpleLength
when possible, or aCSSCalcLength
otherwise. The function will throw aSyntaxError
, when the DOMString it is passed doesn’t represent a valid length. -
from(double value, LengthType type)
-
Constructs a
CSSSimpleLength
with the given value and unit type. -
from(CSSLengthCalcDictionary dictionary)
-
Constructs a
CSSCalcLength
with units and values as defined by the provided dictionary.
4.5. CSSAngleValue
objects
enum CSSAngleUnit { "deg", "rad", "grad", "turn" }; [Constructor(double value, CSSAngleUnit unit)] interface CSSAngleValue : CSSStyleValue { readonly attribute double degrees; readonly attribute double radians; readonly attribute double gradians; readonly attribute double turns; };
CSSAngleValue
objects represent CSS angles. Once constructed, a
CSSAngleValue provides attributes that reflect the size of the angle in each of the
CSS angle units represented by the CSSAngleUnit
enum.
4.6. CSSTransformValue
objects
[Constructor(), Constructor(sequence<CSSTransformComponent> transforms)] interface CSSTransformValue : CSSStyleValue { iterable<CSSTransformComponent>; readonly attribute boolean is2D; readonly attribute DOMMatrixReadOnly matrix; }; interface CSSTransformComponent { readonly attribute DOMString cssText; readonly attribute boolean is2D; readonly attribute DOMMatrixReadOnly matrix; }; [Constructor(CSSLengthValue x, CSSLengthValue y), Constructor(CSSLengthValue x, CSSLengthValue y, CSSLengthValue z)] interface CSSTranslation : CSSTransformComponent { readonly attribute CSSLengthValue x; readonly attribute CSSLengthValue y; readonly attribute CSSLengthValue z; }; [Constructor(CSSAngleValue angle), Constructor(double x, double y, double z, CSSAngleValue angle)] interface CSSRotation : CSSTransformComponent { readonly attribute double x; readonly attribute double y; readonly attribute double z; readonly attribute CSSAngleValue angle; }; [Constructor(double x, double y), Constructor(double x, double y, double z)] interface CSSScale : CSSTransformComponent { readonly attribute double x; readonly attribute double y; readonly attribute double z; }; [Constructor(CSSAngleValue ax, CSSAngleValue ay)] interface CSSSkew : CSSTransformComponent { readonly attribute CSSAngleValue ax; readonly attribute CSSAngleValue ay; }; [Constructor(CSSLengthValue length)] interface CSSPerspective : CSSTransformComponent { readonly attribute CSSLengthValue length; }; [Constructor(DOMMatrixReadOnly matrix)] interface CSSMatrixComponent : CSSTransformComponent { };
CSSTransformValue
objects represent values for the transform property. A CSSTransformValue
represents a list of CSSTransformComponent
s.
CSSTransformComponent
objects have the following properties:
The is2D attribute is true if the component represents a 2D transform function, and false otherwise. The transform function which the component represents is stored in string form in the cssText attribute.
CSSTransformComponent
can correspond to one of a number of underlying
transform functions. For example, a CSSTranslation
with an x value of "10px"
and y & z values of 0 could be:
-
translate(10px)
-
translate(10px, 0)
-
translateX(10px)
-
translate3d(10px, 0, 0)
When a CSSTransformValue
is read from a StylePropertyMap
, each CSSTransformComponent
will maintain the relevant transform function in
its cssText
attribute. However, newly constructed CSSTransformValue
s
will always generate cssText
according to the following rules:
-
CSSSkew
will always serialize to skew(ax, ay) -
CSSPerspective
will always serialize to perspective(length) -
CSSTranslation
,CSSRotation
, andCSSScale
each have two constructors. In each case, the constructor with fewer arguments constructs aCSSTransformComponent
for whichis2D
will be true, withcssText
employing the 2D version of the relevant transform function (translate, rotate, scale). The constructor with more arguments constructs aCSSTransformComponent
for whichis2D
will be false, withcssText
employing the 3D version of the relevant transform function (translate3d, rotate3d, scale3d). -
CSSMatrixComponent
objects are constructed around aDOMMatrixReadOnly
, and well serialize to a matrix function if the containedDOMMatrixReadOnly
'sis2D
attribute is false, and a matrix3d function otherwise.
is2D is true if the is2D
attribute of every CSSTransformComponent
referenced by the CSSTransformValue
returns true, and false otherwise.
4.7. CSSPositionValue
objects
[Constructor(CSSLengthValue x, CSSLengthValue y)] interface CSSPositionValue : CSSStyleValue { readonly attribute CSSLengthValue x; readonly attribute CSSLengthValue y; };
CSSPositionValue
objects represent values for properties that take <position> productions, for example background-position.
The x attribute contains the position offset from the left edge of the container, expressed as a length.
The y attribute contains the position offset from the top edge of the container, expressed as a length.
Note that <position> productions accept a complicated combination of keywords
and values. When specified as such in a stylesheet or via the untyped CSSOM,
the cssText
attribute will contain the specified
string. However, this string is normalized as two Lengths into the x and y
values of the CSSStyleValue
object.
New CSSPositionValue
objects can only be constructed via pairs of lengths, and
will only return the direct serialization of these lengths in the cssText
attribute.
For example, the following style sheet:
.example { background-position: center bottom 10px; }
Will produce the following behavior:
// "center bottom 10px" document.querySelector('.example').styleMap.get('background-position').cssText; // 50% - as a CSSSimpleLength document.querySelector('.example').styleMap.get('background-position').x; // calc(100% - 10px) - as a CSSCalcLength document.querySelector('.example').styleMap.get('background-position').y;
4.8. CSSResourceValue
objects
enum CSSResourceState {"unloaded", "loading", "loaded", "error"}; interface CSSResourceValue : CSSStyleValue { readonly attribute CSSResourceState state; };
CSSResourceValue
objects represent CSS values that may require an asynchronous network fetch
before being usable.
A CSSResourceValue
is in one of the following states, as reflected in the value of the state
attribute:
-
"unloaded"
-
The resource is not ready and is not actively being fetched
-
"loading"
-
The resource is not ready, but is in the process of being fetched
-
"loaded"
-
The resource is ready for rendering
-
"error"
-
The resource can’t be fetched, or the fetched resource is invalid
CSSResourceValue
objects represent this by
providing values that track loaded state via the CSSResourceState
enum. 4.9. CSSImageValue
objects
interface CSSImageValue : CSSResourceValue { readonly attribute double? intrinsicWidth; readonly attribute double? intrinsicHeight; readonly attribute double? intrinsicRatio; }; [Constructor(DOMString url)] interface CSSURLImageValue : CSSImageValue { readonly attribute DOMString url; };
CSSImageValue
objects represent values for properties that take <image> productions,
for example background-image, list-style-image, and border-image-source.
CSSImageValue
objects that do not require network data (for example linear and radial gradients)
are initialized with state
"loaded".
If the CSSImageValue
's state
is "loaded",
and the resource has an intrinsic width, height, or aspect ratio,
then intrinsicWidth
, intrinsicHeight
, and intrinsicRatio
must reflect the resource’s corresponding value.
In all other cases, the attributes must be null
.
Does the loading lifecycle need to be described here?
CSSURLImageValue
objects represent CSSImageValue
s that match the <url> production. For these
objects, the url
attribute contains the URL that references the image.
4.10. CSSFontFaceValue
objects
[Constructor(DOMString fontFaceName)] interface CSSFontFaceValue : CSSResourceValue { readonly attribute DOMString fontFaceName; };
CSSFontFaceValue
objects are opaque representations of the contents of
@font-face rules. They are used to pass font information into paint image definitions,
via custom properties.
As font data may need to be fetched from a remote source, CSSFontFaceValue
is a subclass
of CSSResourceValue
.
Spec up ColorValue <https://github.com/w3c/css-houdini-drafts/issues/159>
5. CSSStyleValue
normalization
This section describes how normalized CSSStyleValue
objects are
constructed from CSS DOMString values.
Strings are normalized by resulting CSSStyleValue subclass. To determine which subclass to use, the CSS property that the string is a value for is used to look up the table in REPLACEME. The normalization procedure defined by each of the CSSStyleValue subclasses listed for that property in turn, falling back to the next subclass in the list if the current one fails to normalize.
If all listed subclasses fail, then the value is normalized as a raw CSSStyleValue
, with the cssText
attribute
set to the input value.
5.1. CSSUnparsedValue
normalization
Values which contain custom property references are tokenized then split into runs of tokens separated by custom property references.
The token runs are serialized, while each custom property reference
is represented by a CSSVariableReferenceValue
.
The string "calc(42px + var(--foo, 15em) + var(--bar, var(--far) + 15px))"
is converted into a CSSUnparsedValue
that contains a sequence with:
-
the string "calc(42px + "
-
a
CSSVariableReferenceValue
with:-
variable
"--foo" -
fallback
aCSSUnparsedValue
with a single-valued sequence containing " 15em"
-
-
the string " + "
-
a
CSSVariableReferenceValue
with:-
variable
"--bar" -
fallback
aCSSUnparsedValue
with a sequence containing:-
the string " "
-
a
CSSVariableReferenceValue
with -
the string " + 15px"
-
-
-
the string ")"
5.2. CSSKeywordValue
normalization
If the provided value can tokenize as an <ident-token>, then
a CSSKeywordValue
is constructed with the provided value
as the keywordValue
attribute.
Otherwise, normalization fails.
5.3. CSSNumberValue
normalization
If the provided value can tokenize as a <number-token>, then
a CSSNumberValue
is constructed with the value
attribute set to the number parsed from the <number-token>.
Otherwise, if the provided value can be parsed as a calc expression with a resolved type of <number>, then the expression is solved and
a CSSNumberValue
is constructed with the value
attribute set to the result.
Otherwise, normalization fails.
5.4. CSSLengthValue
normalization
If the provided value matches the <length> production or the <percentage> production then a CSSSimpleLength
is constructed with the value
attribute set to the number part of the length, and the type
set to the unit.
Otherwise, if the provided value can be parsed as a calc expression with a resolved type of <length> or <percentage>, then
a CSSCalcLength
is constructed with each unit that is mentioned in the
calc expression reflected as the matching attribute set to the appropriate
value.
calc(42px + 15% - 42px)
will normalize to a CSSCalcLength
with both the px
and
the percent
attributes set (to 0 and 15
respectively). Even though the two pixel lengths cancel each other, the fact
that pixels are mentioned in the expression means that they’re represented
in the normalized object. Otherwise, normalization fails.
5.5. CSSAngleValue
normalization
If the provided value matches the <angle> production then a CSSAngleValue
is constructed using the CSSAngleValue(double value, CSSAngleUnit unit) constructor, with value set to the number part of the angle,
and unit set to the unit.
Otherwise, normalization fails.
5.6. CSSTransformValue
normalization
If the provided value matches the <transform-list> production then a CSSTransformComponent
is constructed for each matching <transform-function> in the production, and a CSSTransformValue
is constructed around the resulting sequence.
Otherwise, if the provided value is "none", an empty string, or a string containing only whitespace,
then a CSSTransformValue
is constructed around an empty sequence.
Otherwise, normalization fails.
5.7. CSSPositionValue
normalization
If the provided value matches the <position> production, then a CSSPositionValue
is constructed
with x and y components determined via the following process. If this process, or
any sub-process referenced by this process fails, then normalization as a whole fails.
-
Initialize both x and y to a
CSSSimpleLength
value representing 50%. -
If the provided value is a single keyword, length, percentage, or calc expression, then follow the procedure outlined in §5.7.1 Determining x or y from a single value with value given by the provided value and a horizontal bias.
-
Otherwise, if the provided value consists of a combination of two keywords, then:
-
follow the procedure outlined in §5.7.1 Determining x or y from a single value with value given by the first keyword and an auto bias.
-
if bias is horizontal, set it to vertical. Otherwise, set it to horizontal.
-
follow the procedure again with value given by the second keyword, using the existing bias.
-
-
Otherwise, if the provided value consists of a combination of two keywords, lengths, percentages, and calc expressions, then follow the procedure outlined in §5.7.1 Determining x or y from a single value with value given by the first part of the provided value and a horizontal bias, then follow the procedure again with value given by the second part of the provided value and a vertical bias.
-
Otherwise:
-
if the provided value starts with a keyword followed by a length, percentage, or calc expression, then follow the procedure outlined in §5.7.2 Determining x or y from a keyword and a length with keyword set to the keyword, length set to the length, percentage, or calc expression, and auto bias.
-
otherwise, follow the procedure outlined in §5.7.1 Determining x or y from a single value with value set to the first component of the provided value and an auto bias.
-
if bias is horizontal, set it to vertical. Otherwise, set it to horizontal.
-
if the remainder of the provided value is a single keyword, length, percentage or calc expression, follow the procedure outlined in §5.7.1 Determining x or y from a single value with value set to the keyword and the existing bias.
-
otherwise, if the remainder of the provided value consists of a keyword followed by a length, percentage or calc expression, follow the procedure outlined in §5.7.2 Determining x or y from a keyword and a length with keyword set to the keyword, length set to the length, percentage, or calc expression, and the existing bias.
-
Otherwise, the process fails.
-
5.7.1. Determining x or y from a single value
The following process sets a value for either x or y, depending on an input value and bias. The process also updates bias based on the value.
-
If value is the keyword "left" and bias is not vertical, then set x to a
CSSSimpleLength
value representing 0% and bias to horizontal and exit this process. -
If value is the keyword "right" and bias is not vertical, then set x to a
CSSSimpleLength
value representing 100% and bias to horizontal and exit this process. -
If value is the keyword "top" and bias is not horizontal, then set y to a
CSSSimpleLength
value representing 0% and bias to vertical and exit this process. -
If value is the keyword "bottom" and bias is not horizontal, then set y to a
CSSSimpleLength
value representing 100% and bias to vertical and exit this process. -
If value matches the <length-percentage> production, then set norm to the result of normalizing the value according to §5.4 CSSLengthValue normalization. If bias is vertical, set y to norm, otherwise set x to norm and bias to horizontal. Exit this process.
-
If value is not the keyword "center", then this process fails.
5.7.2. Determining x or y from a keyword and a length
The following process sets a value for either x ory, depending on an input keyword, length, and bias. The process also updates bias based on the keyword and length.
-
follow the procedure outlined in §5.7.1 Determining x or y from a single value with value given by keyword, using the provided bias
-
let adjustment be the result of normalizing length according to §5.4 CSSLengthValue normalization.
-
If the keyword is "right" or "bottom", let adjustment be the result of subtracting adjustment from a zero length.
-
amend x (if bias is horizontal) or y (if bias is vertical) by adding adjustment to it.
5.8. CSSResourceValue
normalization
Resource references are normalized by determining whether the reference is invalid
(in which case state
is set to error) or
requires network data (in which case state
is set to loading). If data is not required and the reference is valid then state
is set to loaded.
If state
is set to loading then the image
reference is reevaluated once the pending data becomes available, according to the
same rules referenced above.
Normalization does not fail for CSSResourceValue
objects.
6. CSSStyleValue
Serialization
The way that a CSSStyleValue
serializes is dependent on how the value was constructed.
-
if the value was constructed from a DOMString
-
the serialization is the DOMString from which the value was constructed.
-
otherwise, if the value was constructed using an IDL constructor
-
the serialization is specified in the sections below.
-
otherwise, if the value was extracted from the CSSOM
-
the serialization matches the CSSOM serialization of the corresponding value.
For example:
var length1 = CSSLengthValue.from("42.0px"); length1.cssText; // "42.0px" var length2 = CSSLengthValue.from(42.0, "px"); length2.cssText; // "42px"; element.style.width = "42.0px"; var length3 = element.styleMap.get('width'); length3.cssText; // "42px";
6.1. CSSUnparsedValue
Serialization
CSSUnparsedValue
objects are serialized by first serializing each CSSVariableReferenceValue
, then concatenating the contained DOMStrings and CSSVariableReferenceValue
serializations in order.
CSSVariableReferenceValue
objects are serialized by the following process:
-
the fallback
CSSUnparsedValue
is serialized -
if the fallback serialization is the empty string, then the
CSSVariableReferenceValue
serializes as "var(" + variable + ")" -
otherwise, the
CSSVariableReferenceValue
serializes as "var(" + variable + "," + fallback serialization + ")"
6.2. CSSKeywordValue
Serialization
CSSKeywordValue
objects are serialized to their contained keywordValue attribute.
6.3. CSSNumberValue
Serialization
CSSNumberValue
objects are serialized to the string representation
of their contained value attribute.
6.4. CSSLengthValue
Serialization
CSSSimpleLength
objects are serialized by appending their contained type to the string representation of
their contained value attribute.
CSSCalcLength
objects are serialized into a calc expression. Each
type attribute that is present (i.e. not undefined) on the object forms
a clause in the expression, with the clauses sorted in IDL specification
order.
6.5. CSSAngleValue
Serialization
CSSAngleValue
objects are serialized by appending "deg" to the
string representation of their contained degrees attribute.
6.6. CSSTransformValue
Serialization
CSSTransformValue
objects are serialized by generating a space-separated list
of serializations of the contained CSSTransformComponent
objects.
CSSTransformComponent
objects are serialized according to the following rules:
-
For all objects except
CSSMatrixComponent
objects, the serialization is defined by the object constructors. -
When there are multiple constructors for a
CSSMatrixComponent
object, then if the is2D attribute is set to true, then the relevant constructor is the constructor with fewer arguments; otherwise the relevant constructor is the constructor with more arguments. -
Each serialization is represented by a function
-
The function’s name is a lowercase version of the component object type, without the CSS prefix
-
The function’s arguments are a comma-separated list that matches the arguments to the relevant constructor. The values of the arguments are given by the attributes contained in the
CSSTransformComponent
. -
CSSLengthValue
andCSSAngleValue
attributes serialize using the rules above. doubles serialize to their string representation. -
CSSMatrixComponent
objects serialize to a list of 6 components if is2D is set, or 12 components otherwise. Component order and format is given by [CSS-TRANSFORMS-1].
6.7. CSSPositionValue
Serialization
CSSPositionValue
objects are serialized by:
-
serializing the x attribute according to the rules for
CSSLengthValue
objects above. -
serializing the y attribute according to the rules for
CSSLengthValue
objects above. -
returning the concatenation of the two serializations (x before y), separated by a space.
6.8. CSSURLImageValue
Serialization
CSSURLImageValue
objects are serialized to the string given by
"url(" + url + ")".
6.9. CSSFontFaceValue
Serialization
CSSFontFaceValue
objects are serialized to the value of their contained fontFaceName.
7. Security Considerations
There are no known security issues introduced by these features.
8. Privacy Considerations
There are no known privacy issues introduced by these features.
Appendix A: Computed CSSStyleValue
objects
This appendix describes the restrictions on CSSStyleValue
objects that
appear as computed values (i.e. as a value stored on computed StylePropertyMapReadOnly
objects).
Computed CSSUnparsedValue
objects
A property with a specified CSSUnparsedValue
value will not
compute to a CSSUnparsedValue
. Instead, after custom property references
are resolved, the CSSStyleValue
subclass appropriate to the property will be
used.
width: calc(var(--foo) + 10%);
Will represent a specified width as an CSSUnparsedValue
, but if this value
is the winning value during computation for a given element then that element’s
computed width will be represented by a CSSLengthValue
object (assuming
that --foo resolves to a valid substitution).
Often there will be no CSSStyleValue
subclass appropriate - for example when a custom property
contains a reference to another custom property. In these cases, a CSSStyleValue
is used directly to represent a valud of unknown type.
For example, a style rule containing:
--foo: var(--bar) black;
Will represent a specified value for --foo as a CSSUnparsedValue
, and if
this value is the winning declaration for --foo during computation for a given
element, then that element’s will have a computed value for --foo that is
represented by a CSSStyleValue
.
Computed CSSKeywordValue
objects
During computation, CSSKeywordValue
objects are either as specified (e.g. auto values for lengths that participate in layout) or resolved to a relevant value
and renormalized (e.g. the color red).
Computed CSSNumberValue
objects
During computation, CSSNumberValue
objects are range-restricted or rounded as
appropriate to the relevant property, but otherwise as specified (see the example
in §4.3 CSSNumberValue objects).
Computed CSSLengthValue
objects
During computation, CSSLengthValue
objects are reduced to combinations of
pixel and percentage values by the standard length computation process described
as part of the <length> type. Lengths may then be further range-restricted as appropriate
(for example, border-left-width requires non-negative lengths).
Note that lengths combining percentage and pixel units can’t in general be range restricted (e.g. is 100px - 50% greater or less than zero?).
Computed CSSAngleValue
objects
Computed CSSAngleValue
objects are as specified.
Computed CSSTransformValue
objects
During computation, any CSSLengthValue
objects referenced by a CSSTransformComponent
(e.g. the x
attribute of a CSSTranslation
) are
computed according to Computed CSSLengthValue objects, but the CSSTransformValue
object is otherwise as specified.
Computed CSSPositionValue
objects
During computation, both the x
and y
components of a CSSPositionValue
are
computed according to Computed CSSLengthValue objects.
Computed CSSImageValue
objects
Computed CSSImageValue
objects are as specified.
Computed CSSFontFaceValue
objects
Computed CSSFontFaceValue
objects are as specified.