CSS Object Model (CSSOM)

Editor’s Draft,

More details about this document
This version:
https://drafts.csswg.org/cssom/
Latest published version:
https://www.w3.org/TR/cssom-1/
Previous Versions:
Feedback:
CSSWG Issues Repository
Inline In Spec
Editors:
(Disruptive Innovations)
(Mozilla)
Former Editors:
(Opera Software AS)
Glenn Adams (Cox Communications, Inc.)
Anne van Kesteren (Opera Software ASA)
Suggest an Edit for this Spec:
GitHub Editor
Legacy issues list:
Bugzilla

Abstract

CSSOM defines APIs (including generic parsing and serialization rules) for Media Queries, Selectors, and of course CSS itself.

CSS is a language for describing the rendering of structured documents (such as HTML and XML) on screen, on paper, etc.

Status of this document

This is a public copy of the editors’ draft. It is provided for discussion only and may change at any moment. Its publication here does not imply endorsement of its contents by W3C. Don’t cite this document other than as work in progress.

Please send feedback by filing issues in GitHub (preferred), including the spec code “cssom” in the title, like this: “[cssom] …summary of comment…”. All issues and comments are archived. Alternately, feedback can be sent to the (archived) public mailing list [email protected].

This document is governed by the 18 August 2025 W3C Process Document.

1. Introduction

This document formally specifies the core features of the CSS Object Model (CSSOM). Other documents in the CSSOM family of specifications as well as other CSS related specifications define extensions to these core features.

The core features of the CSSOM are oriented towards providing basic capabilities to author-defined scripts to permit access to and manipulation of style related state information and processes.

The features defined below are fundamentally based on prior specifications of the W3C DOM Working Group, primarily [DOM]. The purposes of the present document are (1) to improve on that prior work by providing more technical specificity (so as to improve testability and interoperability), (2) to deprecate or remove certain less-widely implemented features no longer considered to be essential in this context, and (3) to newly specify certain extensions that have been or expected to be widely implemented.

2. Terminology

This specification employs certain terminology from the following documents: DOM, HTML, CSS Syntax, Encoding, URL, Fetch, Associating Style Sheets with XML documents and XML. [DOM] [HTML] [CSS3SYN] [ENCODING] [URL] [FETCH] [XML-STYLESHEET] [XML]

When this specification talks about object A where A is actually an interface, it generally means an object implementing interface A.

The terms set and unset to refer to the true and false values of binary flags or variables, respectively. These terms are also used as verbs in which case they refer to mutating some value to make it true or false, respectively.

The term supported styling language refers to CSS.

Note: If another styling language becomes supported in user agents, this specification is expected to be updated as necessary.

The term supported CSS property refers to a CSS property that the user agent implements, including any vendor-prefixed properties, but excluding custom properties. A supported CSS property must be in its lowercase form for the purpose of comparisons in this specification.

In this specification the ::before and ::after pseudo-elements are assumed to exist for all elements even if no box is generated for them.

When a method or an attribute is said to call another method or attribute, the user agent must invoke its internal API for that attribute or method so that e.g. the author can’t change the behavior by overriding attributes or methods with custom properties or functions in ECMAScript.

Unless otherwise stated, string comparisons are done in a case-sensitive manner.

2.1. Common Serializing Idioms

To escape a character means to create a string of "\" (U+005C), followed by the character.

To escape a character as code point means to create a string of "\" (U+005C), followed by the Unicode code point as the smallest possible number of hexadecimal digits in the range 0-9 a-f (U+0030 to U+0039 and U+0061 to U+0066) to represent the code point in base 16, followed by a single SPACE (U+0020).

To serialize an identifier means to create a string represented by the concatenation of, for each character of the identifier:

To serialize a function func, returning a string:
  1. Let s be an empty string.

  2. Serialize an identifier from func’s name, ASCII lowercased, and append the result to s.

  3. Append "(" (U+0028) to s.

  4. Serialize func’s contents, either as specified by the definition of func, or in the shortest form possible (akin to the principles captured by serialize a CSS value). Append the result to s.

  5. Append ")" (U+0029) to s.

  6. Return s.

To serialize a string means to create a string represented by '"' (U+0022), followed by the result of applying the rules below to each character of the given string, followed by '"' (U+0022):

Note: "'" (U+0027) is not escaped because strings are always serialized with '"' (U+0022).

To serialize a URL means to create a string represented by "url(", followed by the serialization of the URL as a string, followed by ")".

To serialize a LOCAL means to create a string represented by "local(", followed by the serialization of the LOCAL as a string, followed by ")".

To serialize a comma-separated list concatenate all items of the list in list order while separating them by ", ", i.e., COMMA (U+002C) followed by a single SPACE (U+0020).

To serialize a whitespace-separated list concatenate all items of the list in list order while separating them by " ", i.e., a single SPACE (U+0020).

Note: When serializing a list according to the above rules, extraneous whitespace is not inserted prior to the first item or subsequent to the last item. Unless otherwise specified, an empty list is serialized as the empty string.

3. CSSOMString

Most strings in CSSOM interfaces use the CSSOMString type. Each implementation chooses to define it as either USVString or DOMString:

typedef USVString CSSOMString;

Or, alternatively:

typedef DOMString CSSOMString;
The difference is only observable from web content when surrogate code units are involved. DOMString would preserve them, whereas USVString would replace them with U+FFFD REPLACEMENT CHARACTER.

This choice effectively allows implementations to do this replacement, but does not require it.

Using USVString enables an implementation to use UTF-8 internally to represent strings in memory. Since well-formed UTF-8 specifically disallows surrogate code points, it effectively requires this replacement.

On the other hand, implementations that internally represent strings as 16-bit code units might prefer to avoid the cost of doing this replacement.

4. Media Queries

Media queries are defined by [MEDIAQUERIES]. This section defines various concepts around media queries, including their API and serialization form.

4.1. Parsing Media Queries

To parse a media query list for a given string s into a media query list is defined in the Media Queries specification. Return the list of media queries that the algorithm defined there gives.

Note: A media query that ends up being "ignored" will turn into "not all".

To parse a media query for a given string s means to follow the parse a media query list steps and return null if more than one media query is returned or a media query if a single media query is returned.

Note: Again, a media query that ends up being "ignored" will turn into "not all".

4.2. Serializing Media Queries

To serialize a media query list run these steps:

  1. If the media query list is empty, then return the empty string.
  2. Serialize each media query in the list of media queries, in the same order as they appear in the media query list, and then serialize the list.

To serialize a media query let s be the empty string, run the steps below:

  1. If the media query is negated append "not", followed by a single SPACE (U+0020), to s.
  2. Let type be the serialization as an identifier of the media type of the media query, converted to ASCII lowercase.
  3. If the media query does not contain media features append type, to s, then return s.
  4. If type is not "all" or if the media query is negated append type, followed by a single SPACE (U+0020), followed by "and", followed by a single SPACE (U+0020), to s.
  5. Then, for each media feature:
    1. Append a "(" (U+0028), followed by the media feature name, converted to ASCII lowercase, to s.
    2. If a value is given append a ":" (U+003A), followed by a single SPACE (U+0020), followed by the serialized media feature value, to s.
    3. Append a ")" (U+0029) to s.
    4. If this is not the last media feature append a single SPACE (U+0020), followed by "and", followed by a single SPACE (U+0020), to s.
  6. Return s.
Here are some examples of input (first column) and output (second column):
Input Output
not screen and (min-WIDTH:5px) AND (max-width:40px)
not screen and (min-width: 5px) and (max-width: 40px)
all and (color) and (color)
(color) and (color)

4.2.1. Serializing Media Feature Values

This should probably be done in terms of mapping it to serializing CSS values as media features are defined in terms of CSS values after all.

To serialize a media feature value named v locate v in the first column of the table below and use the serialization format described in the second column:

Media Feature Serialization
width ...
height ...
device-width ...
device-height ...
orientation If the value is portrait: "portrait". If the value is landscape: "landscape".
aspect-ratio ...
device-aspect-ratio ...
color ...
color-index ...
monochrome ...
resolution ...
scan If the value is progressive: "progressive". If the value is interlace: "interlace".
grid ...

Other specifications can extend this table and vendor-prefixed media features can have custom serialization formats as well.

4.3. Comparing Media Queries

To compare media queries m1 and m2 means to serialize them both and return true if they are a case-sensitive match and false if they are not.

4.4. The MediaList Interface

An object that implements the MediaList interface has an associated collection of media queries.

[Exposed=Window]
interface MediaList {
  stringifier attribute [LegacyNullToEmptyString] CSSOMString mediaText;
  readonly attribute unsigned long length;
  getter CSSOMString? item(unsigned long index);
  undefined appendMedium(CSSOMString medium);
  undefined deleteMedium(CSSOMString medium);
};

The object’s supported property indices are the numbers in the range zero to one less than the number of media queries in the collection of media queries represented by the collection. If there are no such media queries, then there are no supported property indices.

To create a MediaList object with a string text, run the following steps:

  1. Create a new MediaList object.
  2. Set its mediaText attribute to text.
  3. Return the newly created MediaList object.

The mediaText attribute, on getting, must return a serialization of the collection of media queries. Setting the mediaText attribute must run these steps:

  1. Empty the collection of media queries.
  2. If the given value is the empty string, then return.
  3. Append all the media queries as a result of parsing the given value to the collection of media queries.

The item(index) method must return a serialization of the media query in the collection of media queries given by index, or null, if index is greater than or equal to the number of media queries in the collection of media queries.

The length attribute must return the number of media queries in the collection of media queries.

The appendMedium(medium) method must run these steps:

  1. Let m be the result of parsing the given value.
  2. If m is null, then return.
  3. If comparing m with any of the media queries in the collection of media queries returns true, then return.
  4. Append m to the collection of media queries.

The deleteMedium(medium) method must run these steps:

  1. Let m be the result of parsing the given value.
  2. If m is null, then return.
  3. Remove any media query from the collection of media queries for which comparing the media query with m returns true. If nothing was removed, then throw a NotFoundError exception.

5. Selectors

Selectors are defined in the Selectors specification. This section mainly defines how to serialize them.

5.1. Parsing Selectors

To parse a group of selectors means to parse the value using the selectors_group production defined in the Selectors specification and return either a group of selectors if parsing did not fail or null if parsing did fail.

5.2. Serializing Selectors

To serialize a group of selectors serialize each selector in the group of selectors and then serialize a comma-separated list of these serializations.

To serialize a selector let s be the empty string, run the steps below for each part of the chain of the selector, and finally return s:

  1. If there is only one simple selector in the compound selectors which is a universal selector, append the result of serializing the universal selector to s.
  2. Otherwise, for each simple selector in the compound selectors that is not a universal selector of which the namespace prefix maps to a namespace that is not the default namespace serialize the simple selector and append the result to s.
  3. If this is not the last part of the chain of the selector append a single SPACE (U+0020), followed by the combinator ">", "+", "~", ">>", "||", as appropriate, followed by another single SPACE (U+0020) if the combinator was not whitespace, to s.
  4. If this is the last part of the chain of the selector and there is a pseudo-element, append "::" followed by the name of the pseudo-element, to s.

To serialize a simple selector let s be the empty string, run the steps below, and finally return s:

type selector
universal selector
  1. If the namespace prefix maps to a namespace that is not the default namespace and is not the null namespace (not in a namespace) append the serialization of the namespace prefix as an identifier, followed by a "|" (U+007C) to s.
  2. If the namespace prefix maps to a namespace that is the null namespace (not in a namespace) append "|" (U+007C) to s.
  3. If this is a type selector append the serialization of the element name as an identifier to s.
  4. If this is a universal selector append "*" (U+002A) to s.
attribute selector
  1. Append "[" (U+005B) to s.
  2. If the namespace prefix maps to a namespace that is not the null namespace (not in a namespace) append the serialization of the namespace prefix as an identifier, followed by a "|" (U+007C) to s.
  3. Append the serialization of the attribute name as an identifier to s.
  4. If there is an attribute value specified, append "=", "~=", "|=", "^=", "$=", or "*=" as appropriate (depending on the type of attribute selector), followed by the serialization of the attribute value as a string, to s.
  5. If the attribute selector has the case-sensitivity flag present, append " i" (U+0020 U+0069) to s.
  6. Append "]" (U+005D) to s.
class selector
Append a "." (U+002E), followed by the serialization of the class name as an identifier to s.
ID selector
Append a "#" (U+0023), followed by the serialization of the ID as an identifier to s.
pseudo-class
If the pseudo-class does not accept arguments append ":" (U+003A), followed by the name of the pseudo-class, to s.

Otherwise, append ":" (U+003A), followed by the name of the pseudo-class, followed by "(" (U+0028), followed by the value of the pseudo-class argument(s) determined as per below, followed by ")" (U+0029), to s.

:lang()
The serialization of a comma-separated list of each argument’s serialization as a string, preserving relative order.
:nth-child()
:nth-last-child()
:nth-of-type()
:nth-last-of-type()
The result of serializing the value using the rules to serialize an <an+b> value.
:not()
The result of serializing the value using the rules for serializing a group of selectors.

6. CSS

6.1. CSS Style Sheets

A CSS style sheet is an abstract concept that represents a style sheet as defined by the CSS specification. In the CSSOM a CSS style sheet is represented as a CSSStyleSheet object.

CSSStyleSheet(options)
When called, execute the steps to create a constructed CSSStyleSheet given options and return the result.
To create a constructed CSSStyleSheet
given CSSStyleSheetInit options, run these steps:
  1. Construct a new CSSStyleSheet object sheet.
  2. Set sheet’s location to the base URL of the associated Document for the current global object.
  3. Set sheet’s stylesheet base URL to the baseURL attribute value from options.
  4. Set sheet’s parent CSS style sheet to null.
  5. Set sheet’s owner node to null.
  6. Set sheet’s owner CSS rule to null.
  7. Set sheet’s title to the empty string.
  8. Unset sheet’s alternate flag.
  9. Set sheet’s origin-clean flag.
  10. Set sheet’s constructed flag.
  11. Set sheet’s Constructor document to the associated Document for the current global object.
  12. If the media attribute of options is a string, create a MediaList object from the string and assign it as sheet’s media. Otherwise, serialize a media query list from the attribute and then create a MediaList object from the resulting string and set it as sheet’s media.
  13. If the disabled attribute of options is true, set sheet’s disabled flag.
  14. Return sheet.

A CSS style sheet has a number of associated state items:

type
The literal string "text/css".
location
Specified when created. The absolute-URL string of the first request of the CSS style sheet or null if the CSS style sheet was embedded. Does not change during the lifetime of the CSS style sheet.
parent CSS style sheet
Specified when created. The CSS style sheet that is the parent of the CSS style sheet or null if there is no associated parent.
owner node
Specified when created. The DOM node associated with the CSS style sheet or null if there is no associated DOM node.
owner CSS rule
Specified when created. The CSS rule in the parent CSS style sheet that caused the inclusion of the CSS style sheet or null if there is no associated rule.
media
Specified when created. The MediaList object associated with the CSS style sheet.

If this property is specified to a string, the media must be set to the return value of invoking create a MediaList object steps for that string.

If this property is specified to an attribute of the owner node, the media must be set to the return value of invoking create a MediaList object steps for the value of that attribute. Whenever the attribute is set, changed or removed, the media’s mediaText attribute must be set to the new value of the attribute, or to null if the attribute is absent.

Note: Changing the media’s mediaText attribute does not change the corresponding attribute on the owner node.

Note: The owner node of a CSS style sheet, if non-null, is the node whose associated CSS style sheet is the CSS style sheet in question, when the CSS style sheet is added.

title
Specified when created. The title of the CSS style sheet, which can be the empty string.
In the following, the title is non-empty for the first style sheet, but is empty for the second and third style sheets.
<style title="papaya whip">
  body { background: #ffefd5; }
</style>
<style title="">
  body { background: orange; }
</style>
<style>
  body { background: brown; }
</style>

If this property is specified to an attribute of the owner node, the title must be set to the value of that attribute. Whenever the attribute is set, changed or removed, the title must be set to the new value of the attribute, or to the empty string if the attribute is absent.

Note: HTML only specifies title to be an attribute of the owner node if the node is in in a document tree.

alternate flag
Specified when created. Either set or unset. Unset by default.
The following CSS style sheets have their alternate flag set:
<?xml-stylesheet alternate="yes" title="x" href="data:text/css,…"?>
<link rel="alternate stylesheet" title="x" href="data:text/css,…">
disabled flag
Either set or unset. Unset by default.

Note: Even when unset it does not necessarily mean that the CSS style sheet is actually used for rendering.

CSS rules
The CSS rules associated with the CSS style sheet.
origin-clean flag
Specified when created. Either set or unset. If it is set, the API allows reading and modifying of the CSS rules.
constructed flag
Specified when created. Either set or unset. Unset by default. Signifies whether this stylesheet was created by invoking the IDL-defined constructor.
disallow modification flag
Either set or unset. Unset by default. If set, modification of the stylesheet’s rules is not allowed.
constructor document
Specified when created. The Document a constructed stylesheet is associated with. Null by default. Only non-null for stylesheets that have constructed flag set.
stylesheet base URL
The base URL to use when resolving relative URLs in the stylesheet. Null by default. Only non-null for stylesheets that have constructed flag set.

6.1.1. The StyleSheet Interface

The StyleSheet interface represents an abstract, base style sheet.

[Exposed=Window]
interface StyleSheet {
  readonly attribute CSSOMString type;
  readonly attribute USVString? href;
  readonly attribute (Element or ProcessingInstruction)? ownerNode;
  readonly attribute CSSStyleSheet? parentStyleSheet;
  readonly attribute DOMString? title;
  [SameObject, PutForwards=mediaText] readonly attribute MediaList media;
  attribute boolean disabled;
};

The type attribute must return the type.

The href attribute must return the location.

The ownerNode attribute must return the owner node.

The parentStyleSheet attribute must return the parent CSS style sheet.

The title attribute must return the title or null if title is the empty string.

The media attribute must return the media.

The disabled attribute, on getting, must return true if the disabled flag is set, or false otherwise. On setting, the disabled attribute must set the disabled flag if the new value is true, or unset the disabled flag otherwise.

6.1.2. The CSSStyleSheet Interface

The CSSStyleSheet interface represents a CSS style sheet.

[Exposed=Window]
interface CSSStyleSheet : StyleSheet {
  constructor(optional CSSStyleSheetInit options = {});

  readonly attribute CSSRule? ownerRule;
  [SameObject] readonly attribute CSSRuleList cssRules;
  unsigned long insertRule(CSSOMString rule, optional unsigned long index = 0);
  undefined deleteRule(unsigned long index);

  Promise<CSSStyleSheet> replace(USVString text);
  undefined replaceSync(USVString text);
};

dictionary CSSStyleSheetInit {
  DOMString baseURL = null;
  (MediaList or DOMString) media = "";
  boolean disabled = false;
};

The ownerRule attribute must return the owner CSS rule. If a value other than null is ever returned, then that same value must always be returned on each get access.

The cssRules attribute must follow these steps:

  1. If the origin-clean flag is unset, throw a SecurityError exception.
  2. Return a read-only, live CSSRuleList object representing the CSS rules.

    Note: Even though the returned CSSRuleList object is read-only (from the perspective of client-authored script), it can nevertheless change over time due to its liveness status. For example, invoking the insertRule() or deleteRule() methods can result in mutations reflected in the returned object.

The insertRule(rule, index) method must run the following steps:

  1. If the origin-clean flag is unset, throw a SecurityError exception.
  2. If the disallow modification flag is set, throw a NotAllowedError DOMException.
  3. Let parsed rule be the return value of invoking parse a rule with rule.
  4. If parsed rule is a syntax error, throw a SyntaxError DOMException.
  5. If parsed rule is an @import rule, and the constructed flag is set, throw a SyntaxError DOMException.
  6. Return the result of invoking insert a CSS rule rule in the CSS rules at index.

The deleteRule(index) method must run the following steps:

  1. If the origin-clean flag is unset, throw a SecurityError exception.
  2. If the disallow modification flag is set, throw a NotAllowedError DOMException.
  3. Remove a CSS rule in the CSS rules at index.

The replace(text) method must run the following steps:

  1. Let promise be a promise.
  2. If the constructed flag is not set, or the disallow modification flag is set, reject promise with a NotAllowedError DOMException and return promise.
  3. Set the disallow modification flag.
  4. In parallel, do these steps:
    1. Let rules be the result of running parse a stylesheet’s contents from text.
    2. If rules contains one or more @import rules, remove those rules from rules.
    3. Set sheet’s CSS rules to rules.
    4. Unset sheet’s disallow modification flag.
    5. Resolve promise with sheet.
  5. Return promise.

The replaceSync(text) method must run the steps to synchronously replace the rules of a CSSStyleSheet on this CSSStyleSheet given text.

To synchronously replace the rules of a CSSStyleSheet on sheet given text, run these steps:

  1. If the constructed flag is not set, or the disallow modification flag is set, throw a NotAllowedError DOMException.
  2. Let rules be the result of running parse a stylesheet’s contents from text.
  3. If rules contains one or more @import rules, remove those rules from rules.
  4. Set sheet’s CSS rules to rules.
6.1.2.1. Deprecated CSSStyleSheet members

Note: These members are required for compatibility with existing sites.

partial interface CSSStyleSheet {
  [SameObject] readonly attribute CSSRuleList rules;
  long addRule(optional DOMString selector = "undefined", optional DOMString style = "undefined", optional unsigned long index);
  undefined removeRule(optional unsigned long index = 0);
};

The rules attribute must follow the same steps as cssRules, and return the same object cssRules would return.

The removeRule(index) method must run the same steps as deleteRule().

The addRule(selector, block, optionalIndex) method must run the following steps:

  1. Let rule be an empty string.
  2. Append selector to rule.
  3. Append " { " to rule.
  4. If block is not empty, append block, followed by a space, to rule.
  5. Append "}" to rule
  6. Let index be optionalIndex if provided, or the number of CSS rules in the stylesheet otherwise.
  7. Call insertRule(), with rule and index as arguments.
  8. Return -1.

Authors should not use these members and should instead use and teach the standard CSSStyleSheet interface defined earlier, which is consistent with CSSGroupingRule.

6.2. CSS Style Sheet Collections

Below various new concepts are defined that are associated with each DocumentOrShadowRoot object.

Each DocumentOrShadowRoot has an associated list of zero or more CSS style sheets, named the document or shadow root CSS style sheets. This is an ordered list that contains:

  1. Any CSS style sheets created from HTTP Link headers, in header order
  2. Any CSS style sheets associated with the DocumentOrShadowRoot, in tree order

Each DocumentOrShadowRoot has an associated list of zero or more CSS style sheets, named the final CSS style sheets. This is an ordered list that contains:

  1. The document or shadow root CSS style sheets.
  2. The contents of DocumentOrShadowRoot’s adoptedStyleSheets' backing list, in array order.

To create a CSS style sheet, run these steps:

  1. Create a new CSS style sheet object and set its properties as specified.
  2. Then run the add a CSS style sheet steps for the newly created CSS style sheet.

    If the origin-clean flag is unset, this can expose information from the user’s intranet.

To add a CSS style sheet, run these steps:

  1. Add the CSS style sheet to the list of document or shadow root CSS style sheets at the appropriate location.
  2. If the CSS style sheet’s owner node contributes a script-blocking style sheet, then user agents must append the owner node to its node document’s script-blocking style sheet set.

    The remainder of these steps deal with the disabled flag.

  3. If the disabled flag is set, then return.
  4. If the title is not the empty string, the alternate flag is unset, and preferred CSS style sheet set name is the empty string change the preferred CSS style sheet set name to the title.
  5. If any of the following is true, then unset the disabled flag and return:
  6. Set the disabled flag.

To remove a CSS style sheet, run these steps:

  1. Remove the CSS style sheet from the list of document or shadow root CSS style sheets.
  2. Set the CSS style sheet’s parent CSS style sheet, owner node and owner CSS rule to null.

A persistent CSS style sheet is a CSS style sheet from the document or shadow root CSS style sheets whose title is the empty string and whose alternate flag is unset.

A CSS style sheet set is an ordered collection of one or more CSS style sheets from the document or shadow root CSS style sheets which have an identical title that is not the empty string.

A CSS style sheet set name is the title the CSS style sheet set has in common.

An enabled CSS style sheet set is a CSS style sheet set of which each CSS style sheet has its disabled flag unset.

To enable a CSS style sheet set with name name, run these steps:

  1. If name is the empty string, set the disabled flag for each CSS style sheet that is in a CSS style sheet set and return.
  2. Unset the disabled flag for each CSS style sheet in a CSS style sheet set whose CSS style sheet set name is a case-sensitive match for name and set it for all other CSS style sheets in a CSS style sheet set.

To select a CSS style sheet set with name name, run these steps:

  1. enable a CSS style sheet set with name name.
  2. Set last CSS style sheet set name to name.

A last CSS style sheet set name is a concept to determine what CSS style sheet set was last selected. Initially its value is null.

A preferred CSS style sheet set name is a concept to determine which CSS style sheets need to have their disabled flag unset. Initially its value is the empty string.

To change the preferred CSS style sheet set name with name name, run these steps:

  1. Let current be the preferred CSS style sheet set name.
  2. Set preferred CSS style sheet set name to name.
  3. If name is not a case-sensitive match for current and last CSS style sheet set name is null enable a CSS style sheet set with name name.

6.2.1. The HTTP Default-Style Header

The HTTP Default-Style header can be used to set the preferred CSS style sheet set name influencing which CSS style sheet set is (initially) the enabled CSS style sheet set.

For each HTTP Default-Style header, in header order, the user agent must change the preferred CSS style sheet set name with name being the value of the header.

6.2.2. The StyleSheetList Interface

The StyleSheetList interface represents an ordered collection of CSS style sheets.

[Exposed=Window]
interface StyleSheetList {
  getter CSSStyleSheet? item(unsigned long index);
  readonly attribute unsigned long length;
};

The object’s supported property indices are the numbers in the range zero to one less than the number of CSS style sheets represented by the collection. If there are no such CSS style sheets, then there are no supported property indices.

The item(index) method must return the indexth CSS style sheet in the collection. If there is no indexth object in the collection, then the method must return null.

The length attribute must return the number of CSS style sheets represented by the collection.

6.2.3. Extensions to the DocumentOrShadowRoot Interface Mixin

partial interface mixin DocumentOrShadowRoot {
  [SameObject] readonly attribute StyleSheetList styleSheets;
  attribute ObservableArray<CSSStyleSheet> adoptedStyleSheets;
};

The styleSheets attribute must return a StyleSheetList collection representing the document or shadow root CSS style sheets.

The set an indexed value algorithm for adoptedStyleSheets, given value and index, is the following:

  1. If value’s constructed flag is not set, or its constructor document is not equal to this DocumentOrShadowRoot’s node document, throw a "NotAllowedError" DOMException.

6.3. Style Sheet Association

This section defines the interface an owner node of a CSS style sheet has to implement and defines the requirements for xml-stylesheet processing instructions and HTTP Link headers when the link relation type is an ASCII case-insensitive match for "stylesheet".

6.3.1. Fetching CSS style sheets

To fetch a CSS style sheet with parsed URL parsed URL, referrer referrer, document document, optionally a set of parameters parameters (used as input to creating a request), and an algorithm for handling the response result processTheResponse that takes a response, follow these steps:
  1. Let origin be document’s origin.
  2. Let request be a new request, with the url parsed URL, origin origin, referrer referrer, and if specified the set of parameters parameters.
  3. Fetch request, with processResponseEndOfBody, given response, being the following steps:
    1. If response is a network error, return.
    2. If document is in quirks mode, response is CORS-same-origin and the Content-Type metadata of response is not a supported styling language change the Content-Type metadata of response to text/css.
    3. If response is not in a supported styling language, return.
    4. Execute processTheResponse given response

6.3.2. The LinkStyle Interface

The associated CSS style sheet of a node is the CSS style sheet in the list of document or shadow root CSS style sheets of which the owner node is said node. This node must also implement the LinkStyle interface.

interface mixin LinkStyle {
  readonly attribute CSSStyleSheet? sheet;
};

The sheet attribute must return the associated CSS style sheet for the node or null if there is no associated CSS style sheet.

In the following fragment, the first style element has a sheet attribute that returns a StyleSheet object representing the style sheet, but for the second style element, the sheet attribute returns null, assuming the user agent supports CSS (text/css), but does not support the (hypothetical) ExampleSheets (text/example-sheets).
<style type="text/css">
  body { background:lime }
</style>
<style type="text/example-sheets">
  $(body).background := lime
</style>

Note: Whether or not the node refers to a style sheet is defined by the specification that defines the semantics of said node.

6.3.3. Requirements on specifications

Specifications introducing new ways of associating style sheets through the DOM should define which nodes implement the LinkStyle interface. When doing so, they must also define when a CSS style sheet is created.

6.3.4. Requirements on user agents Implementing the xml-stylesheet processing instruction

ProcessingInstruction includes LinkStyle;

The prolog refers to nodes that are children of the Document and are not following the Element child of the Document, if any.

When a ProcessingInstruction node node becomes part of the prolog, is no longer part of the prolog, or has its data changed, these steps must be run:
  1. If an instance of this algorithm is currently running for node, abort that instance, and stop the associated fetching if applicable.
  2. If node has an associated CSS style sheet, remove it.
  3. If node is not an xml-stylesheet processing instruction, then return.
  4. If node does not have an href pseudo-attribute, then return.
  5. Let title be the value of the title pseudo-attribute or the empty string if the title pseudo-attribute is not specified.
  6. If there is an alternate pseudo-attribute whose value is a case-sensitive match for "yes" and title is the empty string, then return.
  7. If there is a type pseudo-attribute whose value is not a supported styling language the user agent may return.
  8. Let input URL be the value specified by the href pseudo-attribute.
  9. Let document be node’s node document
  10. Let base URL be document’s document base URL.
  11. Let referrer be document’s address.
  12. Let parsed URL be the return value of invoking the URL parser with the string input URL and the base URL base URL.
  13. If parsed URL is failure, then return.
  14. Fetch a CSS style sheet with parsed URL parsed URL, referrer referrer, document document, and processTheResponse given response being the following steps:
    1. Create a CSS style sheet with the following properties:
      location
      The result of invoking the URL serializer with parsed URL.
      parent CSS style sheet
      null.
      owner node
      node.
      owner CSS rule
      null.
      media
      The value of the media pseudo-attribute if any, or the empty string otherwise.
      title
      title.
      alternate flag
      Set if the alternate pseudo-attribute value is a case-sensitive match for "yes", or unset otherwise.
      origin-clean flag
      Set if response is CORS-same-origin, or unset otherwise.

      The CSS environment encoding is the result of running the following steps:

      1. If the element has a charset pseudo-attribute, get an encoding from that pseudo-attribute’s value. If that succeeds, return the resulting encoding and abort these steps.
      2. Otherwise, return the document’s character encoding. [DOM]

For each HTTP Link header of which one of the link relation types is an ASCII case-insensitive match for "stylesheet" these steps must be run:

  1. Let title be the value of the first of all the title parameters. If there are no such parameters it is the empty string.
  2. If one of the (other) link relation types is an ASCII case-insensitive match for "alternate" and title is the empty string, then return.
  3. Let input URL be the value specified.

    Be more specific

  4. Let base URL be the document’s document base URL.

    Is there a document at this point?

  5. Let referrer be the document’s address.
  6. Let parsed URL be the return value of invoking the URL parser with the string input URL and the base URL base URL.
  7. If parsed URL is failure, then return.
  8. Fetch a CSS style sheet with parsed URL parsed URL, referrer referrer, document being the document, and processTheResponse, given response, being the following steps:

    What if the HTML parser hasn’t decided on quirks/non-quirks yet?

    1. Create a CSS style sheet with the following properties:
      location
      The result of invoking the URL serializer with parsed URL.
      owner node
      null.
      parent CSS style sheet
      null.
      owner CSS rule
      null.
      media
      The value of the first media parameter.
      title
      title.
      alternate flag
      Set if one of the specified link relation type for this HTTP Link header is an ASCII case-insensitive match for "alternate", or false otherwise.
      origin-clean flag
      Set if response is CORS-same-origin, or unset otherwise.

A style sheet referenced by a HTTP Link header using the rules in this section is said to be a style sheet that is blocking scripts if the style sheet was enabled when created, and the user agent hasn’t given up on that particular style sheet yet. A user agent may give up on such a style sheet at any time.

6.4. CSS Rules

A CSS rule is an abstract concept that denotes a rule as defined by the CSS specification. A CSS rule is represented as an object that implements a subclass of the CSSRule interface, and which has the following associated state items:

type
A non-negative integer associated with a particular type of rule. This item is initialized when a rule is created and cannot change.
text
A text representation of the rule suitable for direct use in a style sheet. This item is initialized when a rule is created and can be changed.
parent CSS rule
A reference to an enclosing CSS rule or null. If the rule has an enclosing rule when it is created, then this item is initialized to the enclosing rule; otherwise it is null. It can be changed to null.
parent CSS style sheet
A reference to a parent CSS style sheet or null. This item is initialized to reference an associated style sheet when the rule is created. It can be changed to null.
child CSS rules
A list of child CSS rules. The list can be mutated.

In addition to the above state, each CSS rule may be associated with other state in accordance with its type.

To parse a CSS rule from a string string, run the following steps:

  1. Let rule be the return value of invoking parse a rule with string.
  2. If rule is a syntax error, return rule.
  3. Let parsed rule be the result of parsing rule according to the appropriate CSS specifications, dropping parts that are said to be ignored. If the whole rule is dropped, return a syntax error.
  4. Return parsed rule.

To serialize a CSS rule, perform one of the following in accordance with the CSS rule’s type:

CSSStyleRule
Return the result of the following steps:
  1. Let s initially be the result of performing serialize a group of selectors on the rule’s associated selectors, followed by the string " {", i.e., a single SPACE (U+0020), followed by LEFT CURLY BRACKET (U+007B).
  2. Let decls be the result of performing serialize a CSS declaration block on the rule’s associated declarations, or null if there are no such declarations.
  3. Let rules be the result of performing serialize a CSS rule on each rule in the rule’s cssRules list, or null if there are no such rules.
  4. If decls and rules are both null, append " }" to s (i.e. a single SPACE (U+0020) followed by RIGHT CURLY BRACKET (U+007D)) and return s.
  5. If rules is null:
    1. Append a single SPACE (U+0020) to s
    2. Append decls to s
    3. Append " }" to s (i.e. a single SPACE (U+0020) followed by RIGHT CURLY BRACKET (U+007D)).
    4. Return s.
  6. Otherwise:
    1. If decls is not null, prepend it to rules.
    2. For each rule in rules:
      • If rule is the empty string, do nothing.
      • Otherwise:
        1. Append a newline followed by two spaces to s.
        2. Append rule to s.
    3. Append a newline followed by RIGHT CURLY BRACKET (U+007D) to s.
    4. Return s.
CSSImportRule
The result of concatenating the following:
  1. The string "@import" followed by a single SPACE (U+0020).
  2. The result of performing serialize a URL on the rule’s location.
  3. If the rule’s associated media list is not empty, a single SPACE (U+0020) followed by the result of performing serialize a media query list on the media list.
  4. The string ";", i.e., SEMICOLON (U+003B).
@import url("import.css");
@import url("print.css") print;
CSSMediaRule
The result of concatenating the following:
  1. The string "@media", followed by a single SPACE (U+0020).
  2. The result of performing serialize a media query list on rule’s media query list.
  3. A single SPACE (U+0020), followed by the string "{", i.e., LEFT CURLY BRACKET (U+007B), followed by a newline.
  4. The result of performing serialize a CSS rule on each rule in the rule’s cssRules list, filtering out empty strings, indenting each item with two spaces, all joined with newline.
  5. A newline, followed by the string "}", i.e., RIGHT CURLY BRACKET (U+007D)
CSSFontFaceRule
The result of concatenating the following:
  1. The string "@font-face {", followed by a single SPACE (U+0020).
  2. The string "font-family:", followed by a single SPACE (U+0020).
  3. The result of performing serialize a string on the rule’s font family name.
  4. The string ";", i.e., SEMICOLON (U+003B).
  5. If the rule’s associated source list is not empty, follow these substeps:
    1. A single SPACE (U+0020), followed by the string "src:", followed by a single SPACE (U+0020).
    2. The result of invoking serialize a comma-separated list on performing serialize a URL or serialize a LOCAL for each source on the source list.
    3. The string ";", i.e., SEMICOLON (U+003B).
  6. If rule’s associated unicode-range descriptor is present, a single SPACE (U+0020), followed by the string "unicode-range:", followed by a single SPACE (U+0020), followed by the result of performing serialize a <'unicode-range'>, followed by the string ";", i.e., SEMICOLON (U+003B).
  7. If rule’s associated font-variant descriptor is present, a single SPACE (U+0020), followed by the string "font-variant:", followed by a single SPACE (U+0020), followed by the result of performing serialize a <'font-variant'>, followed by the string ";", i.e., SEMICOLON (U+003B).
  8. If rule’s associated font-feature-settings descriptor is present, a single SPACE (U+0020), followed by the string "font-feature-settings:", followed by a single SPACE (U+0020), followed by the result of performing serialize a <'font-feature-settings'>, followed by the string ";", i.e., SEMICOLON (U+003B).
  9. If rule’s associated font-stretch descriptor is present, a single SPACE (U+0020), followed by the string "font-stretch:", followed by a single SPACE (U+0020), followed by the result of performing serialize a <'font-stretch'>, followed by the string ";", i.e., SEMICOLON (U+003B).
  10. If rule’s associated font-weight descriptor is present, a single SPACE (U+0020), followed by the string "font-weight:", followed by a single SPACE (U+0020), followed by the result of performing serialize a <'font-weight'>, followed by the string ";", i.e., SEMICOLON (U+003B).
  11. If rule’s associated font-style descriptor is present, a single SPACE (U+0020), followed by the string "font-style:", followed by a single SPACE (U+0020), followed by the result of performing serialize a <'font-style'>, followed by the string ";", i.e., SEMICOLON (U+003B).
  12. A single SPACE (U+0020), followed by the string "}", i.e., RIGHT CURLY BRACKET (U+007D).

Need to define how the CSSFontFaceRule descriptors' values are serialized.

CSSPageRule

Need to define how CSSPageRule is serialized.

CSSNamespaceRule
The literal string "@namespace", followed by a single SPACE (U+0020), followed by the serialization as an identifier of the prefix attribute (if any), followed by a single SPACE (U+0020) if there is a prefix, followed by the serialization as URL of the namespaceURI attribute, followed the character ";" (U+003B).
CSSKeyframesRule
The result of concatenating the following:
  1. The literal string "@keyframes", followed by a single SPACE (U+0020).
  2. The serialization of the name attribute. If the attribute is a CSS wide keyword, or the value default, or the value none, then it is serialized as a string. Otherwise, it is serialized as an identifier.
  3. The string " { ", i.e., a single SPACE (U+0020), followed by LEFT CURLY BRACKET (U+007B), followed by a single SPACE (U+0020).
  4. The result of performing serialize a CSS rule on each rule in the rule’s cssRules list, separated by a newline and indented by two spaces.
  5. A newline, followed by the string "}", i.e., RIGHT CURLY BRACKET (U+007D)
CSSKeyframeRule
The result of concatenating the following:
  1. The keyText.
  2. The string " { ", i.e., a single SPACE (U+0020), followed by LEFT CURLY BRACKET (U+007B), followed by a single SPACE (U+0020).
  3. The result of performing serialize a CSS declaration block on the rule’s associated declarations.
  4. If the rule is associated with one or more declarations, the string " ", i.e., a single SPACE (U+0020).
  5. The string "}", RIGHT CURLY BRACKET (U+007D).

The "indented by two spaces" bit matches browsers, but needs work, see #5494

To insert a CSS rule rule in a CSS rule list list at index index, with a flag nested, follow these steps:

  1. Set length to the number of items in list.
  2. If index is greater than length, then throw an IndexSizeError exception.
  3. Set new rule to the results of performing parse a CSS rule on argument rule.
  4. If new rule is a syntax error, and nested is set, perform the following substeps:
  5. If new rule is a syntax error, throw a SyntaxError exception.
  6. If new rule cannot be inserted into list at the zero-indexed position index due to constraints specified by CSS, then throw a HierarchyRequestError exception. [CSS21]

    Note: For example, a CSS style sheet cannot contain an @import at-rule after a style rule.

  7. If new rule is an @namespace at-rule, and list contains anything other than @import at-rules, and @namespace at-rules, throw an InvalidStateError exception.
  8. Insert new rule into list at the zero-indexed position index.
  9. Return index.

To remove a CSS rule from a CSS rule list list at index index, follow these steps:

  1. Set length to the number of items in list.
  2. If index is greater than or equal to length, then throw an IndexSizeError exception.
  3. Set old rule to the indexth item in list.
  4. If old rule is an @namespace at-rule, and list contains anything other than @import at-rules, and @namespace at-rules, throw an InvalidStateError exception.
  5. Remove rule old rule from list at the zero-indexed position index.
  6. Set old rule’s parent CSS rule and parent CSS style sheet to null.

6.4.1. The CSSRuleList Interface

The CSSRuleList interface represents an ordered collection of CSS rules.

[Exposed=Window]
interface CSSRuleList {
  getter CSSRule? item(unsigned long index);
  readonly attribute unsigned long length;
};

The object’s supported property indices are the numbers in the range zero to one less than the number of CSSRule objects represented by the collection. If there are no such CSSRule objects, then there are no supported property indices.

The item(index) method must return the indexth CSSRule object in the collection. If there is no indexth object in the collection, then the method must return null.

The length attribute must return the number of CSSRule objects represented by the collection.

6.4.2. The CSSRule Interface

The CSSRule interface represents an abstract, base CSS rule. Each distinct CSS rule type is represented by a distinct interface that inherits from this interface.

[Exposed=Window]
interface CSSRule {
  attribute CSSOMString cssText;
  readonly attribute CSSRule? parentRule;
  readonly attribute CSSStyleSheet? parentStyleSheet;

  // the following attribute and constants are historical
  readonly attribute unsigned short type;
  const unsigned short STYLE_RULE = 1;
  const unsigned short CHARSET_RULE = 2;
  const unsigned short IMPORT_RULE = 3;
  const unsigned short MEDIA_RULE = 4;
  const unsigned short FONT_FACE_RULE = 5;
  const unsigned short PAGE_RULE = 6;
  const unsigned short MARGIN_RULE = 9;
  const unsigned short NAMESPACE_RULE = 10;
};

The cssText attribute must return a serialization of the CSS rule. On setting the cssText attribute must do nothing.

The parentRule attribute must return the parent CSS rule.

Note: For example, @media can enclose a rule, in which case parentRule would be non-null; in cases where there is no enclosing rule, parentRule will be null.

The parentStyleSheet attribute must return the parent CSS style sheet.

Note: The only circumstance where null is returned when a rule has been removed.

Note: Removing a Node that implements the LinkStyle interface from a Document instance does not (by itself) cause the CSSStyleSheet referenced by a CSSRule to be unreachable.

The type attribute is deprecated. It must return an integer, as follows:

If the object is a CSSStyleRule
Return 1.
If the object is a CSSImportRule
Return 3.
If the object is a CSSMediaRule
Return 4.
If the object is a CSSFontFaceRule
Return 5.
If the object is a CSSPageRule
Return 6.
If the object is a CSSKeyframesRule
Return 7.
If the object is a CSSKeyframeRule
Return 8.
If the object is a CSSMarginRule
Return 9.
If the object is a CSSNamespaceRule
Return 10.
If the object is a CSSCounterStyleRule
Return 11.
If the object is a CSSSupportsRule
Return 12.
If the object is a CSSFontFeatureValuesRule
Return 14.
Otherwise
Return 0.

Note: The practice of using an integer enumeration and several constants to identify the integers is a legacy design practice that is no longer used in Web APIs. Instead, to tell what type of rule a given object is, it is recommended to check rule.constructor.name, which will return a string like "CSSStyleRule". This enumeration is thus frozen in its current state, and no new new values will be added to reflect additional at-rules; all at-rules beyond the ones listed above will return 0.

6.4.3. The CSSStyleRule Interface

The CSSStyleRule interface represents a style rule.

[Exposed=Window]
interface CSSStyleRule : CSSGroupingRule {
  attribute CSSOMString selectorText;
  [SameObject, PutForwards=cssText] readonly attribute CSSStyleProperties style;
};

The selectorText attribute, on getting, must return the result of serializing the rule’s associated selector list. On setting the selectorText attribute these steps must be run:

  1. Run the parse a group of selectors algorithm on the given value.
  2. If the algorithm returns a non-null value replace the associated selector list with the returned value.
  3. Otherwise, if the algorithm returns a null value, do nothing.

The style attribute must return a CSSStyleProperties object for the style rule, with the following properties:

computed flag
Unset.
readonly flag
Unset.
declarations
The declared declarations in the rule, in specified order.
parent CSS rule
this.
owner node
Null.

The specified order for declarations is the same as specified, but with shorthand properties expanded into their longhand properties, in canonical order. If a property is specified more than once (after shorthand expansion), only the one with greatest cascading order must be represented, at the same relative position as it was specified. [CSS3CASCADE]

6.4.4. The CSSImportRule Interface

The CSSImportRule interface represents an @import at-rule.

[Exposed=Window]
interface CSSImportRule : CSSRule {
  readonly attribute USVString href;
  [SameObject, PutForwards=mediaText] readonly attribute MediaList media;
  [SameObject] readonly attribute CSSStyleSheet? styleSheet;
  readonly attribute CSSOMString? layerName;
  readonly attribute CSSOMString? supportsText;
};

The href attribute must return the URL specified by the @import at-rule.

Note: To get the resolved URL use the href attribute of the associated CSS style sheet.

The media attribute must return the value of the media attribute of the associated CSS style sheet.

The styleSheet attribute must return the associated CSS style sheet, if any, or null otherwise.

The layerName attribute must return the layer name declared in the at-rule itself, or an empty string if the layer is anonymous, or null if the at-rule does not declare a layer.

The supportsText attribute must return the <supports-condition> declared in the at-rule itself, or null if the at-rule does not declare a supports condition.

Note: An @import at-rule might not have an associated CSS style sheet (e.g., if it has a non-matching supports() condition).

6.4.5. The CSSGroupingRule Interface

The CSSGroupingRule interface represents an at-rule that contains other rules nested inside itself.

[Exposed=Window]
interface CSSGroupingRule : CSSRule {
  [SameObject] readonly attribute CSSRuleList cssRules;
  unsigned long insertRule(CSSOMString rule, optional unsigned long index = 0);
  undefined deleteRule(unsigned long index);
};

The cssRules attribute must return a CSSRuleList object for the child CSS rules.

The insertRule(rule, index) method must return the result of invoking insert a CSS rule rule into the child CSS rules at index, with the nested flag set.

The deleteRule(index) method must remove a CSS rule from the child CSS rules at index.

6.4.6. The CSSMediaRule Interface

The CSSMediaRule interface is defined in CSS Conditional Rules. [CSS3-CONDITIONAL]

6.4.7. The CSSPageRule Interface

The CSSPageRule interface represents an @page at-rule.

Need to define the rules for parse a list of CSS page selectors and serialize a list of CSS page selectors.

[Exposed=Window]
interface CSSPageDescriptors : CSSStyleDeclaration {
  attribute [LegacyNullToEmptyString] CSSOMString margin;
  attribute [LegacyNullToEmptyString] CSSOMString marginTop;
  attribute [LegacyNullToEmptyString] CSSOMString marginRight;
  attribute [LegacyNullToEmptyString] CSSOMString marginBottom;
  attribute [LegacyNullToEmptyString] CSSOMString marginLeft;
  attribute [LegacyNullToEmptyString] CSSOMString margin-top;
  attribute [LegacyNullToEmptyString] CSSOMString margin-right;
  attribute [LegacyNullToEmptyString] CSSOMString margin-bottom;
  attribute [LegacyNullToEmptyString] CSSOMString margin-left;
  attribute [LegacyNullToEmptyString] CSSOMString size;
  attribute [LegacyNullToEmptyString] CSSOMString pageOrientation;
  attribute [LegacyNullToEmptyString] CSSOMString page-orientation;
  attribute [LegacyNullToEmptyString] CSSOMString marks;
  attribute [LegacyNullToEmptyString] CSSOMString bleed;
};

[Exposed=Window]
interface CSSPageRule : CSSGroupingRule {
           attribute CSSOMString selectorText;
  [SameObject, PutForwards=cssText] readonly attribute CSSPageDescriptors