<pre class='metadata'>
Title: CSS Object Model (CSSOM) Module Level 1
ED: https://drafts.csswg.org/cssom/
TR: https://www.w3.org/TR/cssom-1/
Previous Version: https://www.w3.org/TR/2021/WD-cssom-1-20210826/
Previous Version: https://www.w3.org/TR/2016/WD-cssom-1-20160317/
Previous Version: https://www.w3.org/TR/2013/WD-cssom-20131205/
Previous Version: https://www.w3.org/TR/2011/WD-cssom-20110712/
Previous Version: https://www.w3.org/TR/2000/REC-DOM-Level-2-Style-20001113/
Group: CSSWG
Status: ED
Prepare for TR: no
Work Status: Exploring
Shortname: cssom
Level: 1
Editor: Daniel Glazman, Disruptive Innovations http://disruptive-innovations.com/, daniel.glazman@disruptive-innovations.com, w3cid 13329
Editor: Emilio Cobos Álvarez 106537, Mozilla, emilio@mozilla.com
Former Editor: Simon Pieters, Opera Software AS http://www.opera.com, simonp@opera.com
Former Editor: Glenn Adams, Cox Communications&#44; Inc. http://www.cox.com, glenn.adams@cos.com, http://www.w3.org/wiki/User:Gadams
Former Editor: Anne van Kesteren, Opera Software ASA http://www.opera.com, annevk@annevk.nl, https://annevankesteren.nl/
!Legacy issues list: <a href="https://www.w3.org/Bugs/Public/buglist.cgi?product=CSS&amp;component=CSSOM&amp;resolution=---">Bugzilla</a>
Abstract: CSSOM defines APIs (including generic parsing and serialization rules) for Media Queries, Selectors, and of course CSS itself.
Repository: w3c/csswg-drafts
Ignored Terms: cssText
Ignored Vars: m1, m2, camel_cased_attribute, webkit_cased_attribute, dashed_attribute
WPT Path Prefix: /css/cssom/
WPT Display: closed
Include Can I Use Panels: true
Can I Use URL: https://drafts.csswg.org/cssom/
Can I Use URL: https://www.w3.org/TR/cssom-1/
Ignore Can I Use URL Failure: https://drafts.csswg.org/cssom/
Ignore Can I Use URL Failure: https://www.w3.org/TR/cssom-1/
Ignore MDN Failure: #dom-cssgroupingrule-selectortext
Ignore MDN Failure: #dom-cssgroupingrule-style
Ignore MDN Failure: #dom-cssstyledeclaration-cssfloat
</pre>

<pre class='anchors'>
urlPrefix: https://html.spec.whatwg.org/multipage/
    urlPrefix: infrastructure.html
        type: dfn
            text: html elements
            text: tree order
            text: content-type metadata; url: #content-type
    urlPrefix: urls-and-fetching.html
        type: dfn
            text: document base url
    urlPrefix: rendering.html
        type: dfn
            text: being rendered
    urlPrefix: browsers.html
        type: interface; text: WindowProxy
        type: dfn
            text: browsing context
            text: auxiliary browsing context
            text: familiar with
            text: same origin
    urlPrefix: webappapis.html
        type: dfn
            text: responsible browsing context
            text: incumbent settings object
            text: event loop
            text: event handlers
            text: event handler event type
            text: event handler IDL attributes
    urlPrefix: infrastructure.html
        type: dfn
            text: split a string on commas
            text: skip whitespace
            text: collect a sequence of characters
            text: space character
            text: rules for parsing integers
    urlPrefix: xhtml.html
        type: dfn
            text: xml parser
    urlPrefix: semantics.html
        type: dfn
            text: a style sheet that is blocking scripts
            text: contributes a script-blocking style sheet
            for: Document
                text: script-blocking style sheet set
urlPrefix: https://dom.spec.whatwg.org/#concept-
    type: dfn
        text: dispatch; url: event-dispatch
        text: event
        text: event listener
        text: quirks mode; url: document-quirks
        text: fire an event; url: event-fire
        text: node document
        text: document url
urlPrefix: https://www.w3.org/TR/CSS21/visuren.html
    type: dfn; text: anonymous block box; url: #anonymous-block-level
urlPrefix: http://heycam.github.io/webidl/#
    type: interface; urlPrefix: idl-
        text: double
        text: long
    type: dfn; urlPrefix: dfn-
        text: converted to an IDL value
        text: throw
        text: supported property indices
urlPrefix: https://encoding.spec.whatwg.org/#; spec: ENCODING
    type: dfn; text: get an encoding; url: concept-encoding-get
urlPrefix: https://url.spec.whatwg.org/#concept-
    type: dfn
        text: URL
        text: URL parser
        text: URL serializer
urlPrefix: https://www.w3.org/TR/xml-stylesheet/#dt-
    type: dfn;
        text: xml-stylesheet processing instruction; url: xml-stylesheet
    type: dfn; text: pseudo-attribute
urlPrefix: https://fetch.spec.whatwg.org/#concept-
    type: dfn;
        text: fetch
        text: request
        for: request
            text: url; url: request-url
            text: origin; url: request-origin
            text: referrer; url: request-referrer
        text: network error
</pre>

<pre class='link-defaults'>
spec:css-borders-4; type:property;
    text:border-top-color
    text:border-left-color
    text:border-right-color
    text:border-bottom-color
    text:border-block-start-color
    text:border-block-end-color
    text:border-inline-start-color
    text:border-inline-end-color
    text:box-shadow
spec:css-color-4; type:value; text:color
spec:css-display-3; type:value; for:display; text:table
spec:css-fonts-4; type:descriptor;
    text:unicode-range
    text:font-variant
    text:font-feature-settings
    text:font-stretch
    text:font-weight
    text:font-style
spec:css-logical; type:property; text:inline-size
spec:css-namespaces-3; type:dfn; text:namespace prefix
spec:css-position-3; type:property; text:left
spec:css-values-4; type:dfn; text:keyword
spec:css-variables-1; type:dfn; text:custom property
spec:dom;
    type:interface;
        text:Document
        text:DocumentOrShadowRoot
    type:dfn; text:in a document tree
spec:html; type:element; text:style
spec:infra; type:dfn; text:list
spec:selectors-3; type:selector;
    text:::before
    text:::after
</pre>

<style>
main .atrisk::before {
    float: right;
    margin-top: -0.25em;
    padding: 0.5em 1em 0.5em 0;
    text-indent: -0.9em;
    border: 1px solid;
    content: '\25C0    Not yet widely implemented';
    white-space: pre;
    font-size: small;
    background-color: white;
    color: gray;
    text-align: center;
}
</style>

<script src=https://resources.whatwg.org/file-issue.js async data-file-issue-url="https://github.com/w3c/csswg-drafts/issues/new?title=%5Bcssom%5D%20"></script>

<style>
.selected-text-file-an-issue {
    position: fixed;
    bottom: 0;
    right: 0;
    background: rgba(255, 255, 255, 0.8);
    font-size: smaller;
    padding: 4px 10px;
    z-index: 1;
    text-decoration: underline;
}
@media (max-width: 767px) {
    .selected-text-file-an-issue { left: 0; right: auto; text-align: left; }
}
</style>

Introduction {#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.

<wpt title="Basic CSSOM tests">
  idlharness.html
  invalid-pseudo-elements.html
  historical.html
  stylesheet-replacedata-dynamic.html
  xml-stylesheet-pi-in-doctype.xhtml
</wpt>

Terminology {#terminology}
==========================

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

When this specification talks about object
<code><var>A</var></code> where <code><var>A</var></code> is actually an interface, it generally means an object implementing interface
<code><var>A</var></code>.

The terms <dfn>set</dfn> and <dfn>unset</dfn> 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 <dfn export>supported styling language</dfn> refers to CSS.

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

The term <dfn export>supported CSS property</dfn> refers to a CSS property that the user agent
implements, including any vendor-prefixed properties, but excluding <a>custom properties</a>. A
<a>supported CSS property</a> 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 <a>case-sensitive</a> manner.


Common Serializing Idioms {#common-serializing-idioms}
------------------------------------------------------

To <dfn export>escape a character</dfn> means to create a string of
"<code>\</code>" (U+005C), followed by the character.

To <dfn lt="escape a character as code point|escaped as code point">escape a character as code point</dfn> means to create a
string of "<code>\</code>" (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 <dfn export>serialize an identifier</dfn> means to create a string represented
by the concatenation of, for each character of the identifier:

<ul>
 <li>If the character is NULL (U+0000), then the REPLACEMENT CHARACTER (U+FFFD).
 <li>If the character is in the range [\1-\1f] (U+0001 to U+001F) or is U+007F, then the character
 <a>escaped as code point</a>.
 <li>If the character is the first character and is in the range \[0-9]
 (U+0030 to U+0039), then the character
 <a>escaped as code point</a>.
 <li>If the character is the second character and is in the range \[0-9]
 (U+0030 to U+0039) and the first character is a "<code>-</code>"
 (U+002D), then the character
 <a>escaped as code point</a>.
 <li>If the character is the first character and is a "<code>-</code>" (U+002D),
 and there is no second character,
 then the <a lt="escape a character">escaped</a> character.
 <li>If the character is not handled by one of the above rules and is
 greater than or equal to U+0080, is "<code>-</code>" (U+002D) or
 "<code>_</code>" (U+005F), or is in one of the ranges \[0-9] (U+0030 to
 U+0039), \[A-Z] (U+0041 to U+005A), or \[a-z] (U+0061 to U+007A), then the character
 itself.
 <li>Otherwise, the <a lt="escape a character">escaped</a>
 character.
</ul>

<div algorithm>
    To <dfn export for=CSS>serialize a function</dfn> |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|.
</div>

To <dfn export lt="serialize a string|serialize as a string">serialize a string</dfn> 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):

<ul>
 <li>If the character is NULL (U+0000), then the REPLACEMENT CHARACTER (U+FFFD).
 <li>If the character is in the range [\1-\1f] (U+0001 to U+001F) or is U+007F, the character
 <a>escaped as code point</a>.
 <li>If the character is '"' (U+0022) or "<code>\</code>"
 (U+005C), the <a lt="escape a character">escaped</a> character.
 <li>Otherwise, the character itself.
</ul>

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

To <dfn export>serialize a URL</dfn> means to create a string represented by
"<code>url(</code>", followed by the
<a lt="serialize a string">serialization</a> of the URL as a
string, followed by "<code>)</code>".

To <dfn export>serialize a LOCAL</dfn> means to create a string represented by
"<code>local(</code>", followed by the
<a lt="serialize a string">serialization</a> of the LOCAL as a
string, followed by "<code>)</code>".

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

To <dfn export>serialize a whitespace-separated list</dfn> concatenate all
items of the list in list order while separating them by "<code> </code>", 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.


CSSOMString {#cssomstring-type}
===============================

Most strings in CSSOM interfaces use the <dfn interface>CSSOMString</dfn> type.
Each implementation chooses to define it as either {{USVString}} or {{DOMString}}:

<pre class="def lang-webidl">
typedef USVString CSSOMString;
</pre>

Or, alternatively:

<pre class="def lang-webidl">
typedef DOMString CSSOMString;
</pre>

<div class=note>
  The difference is only observable from web content
  when <a>surrogate</a> 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 <a>surrogate</a> code points,
  it effectively requires this replacement.

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


Media Queries {#media-queries}
==============================

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


Parsing Media Queries {#parsing-media-queries}
----------------------------------------------

To <dfn export>parse a media query list</dfn> for a
given string <var>s</var> into a [=media query list=] is defined in
the Media Queries specification. Return the list of media
queries that the algorithm defined there gives. <!-- XXX ref -->

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

To <dfn export>parse a media query</dfn> for a given string
<var>s</var> means to follow the
<a>parse a media query list</a> 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 "<code>not all</code>".


Serializing Media Queries {#serializing-media-queries}
------------------------------------------------------

To
<dfn export>serialize a media query list</dfn>
run these steps:

<ol>
 <li>If the [=media query list=] is empty, then return the empty string.

 <li><a lt="serialize a media query">Serialize</a> each media query in the list of media queries, in the same order as they appear in the [=media query list=], and then <a lt="serialize a comma-separated list">serialize</a> the list.
</ol>

To
<dfn export>serialize a media query</dfn> let
<var>s</var> be the empty string, run the steps below:

<ol>
 <li>If the [=media query=] is negated append "<code>not</code>", followed
 by a single SPACE (U+0020), to <var>s</var>.

 <li>Let <var>type</var> be the <a lt="serialize an identifier">serialization
 as an identifier</a> of the [=media type=] of the [=media query=],
 <a lt="ASCII lowercase">converted to ASCII lowercase</a>.

 <li>If the [=media query=] does not contain [=media features=] append
 <var>type</var>, to <var>s</var>,
 then return <var>s</var>.

 <li>If <var>type</var> is not "<code>all</code>" or if the
 media query is negated append <var>type</var>, followed by a
 single SPACE (U+0020), followed by "<code>and</code>", followed by a single SPACE
 (U+0020), to <var>s</var>.

 <li>
  Then, for each [=media feature=]:

  <ol>
   <li>Append a "<code>(</code>" (U+0028), followed by the [=media feature=]
   name, <a lt="ASCII lowercase">converted to ASCII lowercase</a>,
   to <var>s</var>.

   <li>If a value is given append a "<code>:</code>" (U+003A), followed
   by a single SPACE (U+0020), followed by the
   <a lt="serialize a media feature value">serialized media feature value</a>,
   to <var>s</var>.

   <li>Append a "<code>)</code>" (U+0029) to
   <var>s</var>.

   <li>If this is not the last [=media feature=] append a single SPACE (U+0020),
   followed by "<code>and</code>", followed by a single SPACE (U+0020), to
   <var>s</var>.
  </ol>

 <li>Return <var>s</var>.

</ol>

<div class="example">
 Here are some examples of input (first column) and output (second
 column):

 <table class="complex data">
  <thead>
   <tr><th>Input<th>Output
  <tbody>
   <tr>
    <td><pre>not screen and (min-WIDTH:5px) AND (max-width:40px)</pre>
    <td><pre>not screen and (min-width: 5px) and (max-width: 40px)</pre>
   <tr>
    <td><pre>all and (color) and (color)</pre>
    <td><pre>(color) and (color)</pre>
 </table>
</div>

<wpt>
  mediaquery-sort-dedup.html
</wpt>

### Serializing Media Feature Values ### {#serializing-media-feature-values}

Issue: 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 <dfn export>serialize a media feature value</dfn>
named <var>v</var> locate <var>v</var> in the first
column of the table below and use the serialization format described in
the second column:

<table class="complex data">
 <thead>
  <tr>
   <th>Media Feature
   <th>Serialization
 <tbody>
  <tr>
   <td>'@media/width!!descriptor'
   <td>...
  <tr>
   <td>'@media/height!!descriptor'
   <td>...
  <tr>
   <td>'@media/device-width!!descriptor'
   <td>...
  <tr>
   <td>'@media/device-height!!descriptor'
   <td>...
  <tr>
   <td>'@media/orientation!!descriptor'
   <td>
    If the value is ''orientation/portrait'': "<code>portrait</code>".
    If the value is ''orientation/landscape'': "<code>landscape</code>".
  <tr>
   <td>'@media/aspect-ratio!!descriptor'
   <td>...
  <tr>
   <td>'@media/device-aspect-ratio!!descriptor'
   <td>...
  <tr>
   <td>'@media/color!!descriptor'
   <td>...
  <tr>
   <td>'@media/color-index!!descriptor'
   <td>...
  <tr>
   <td>'@media/monochrome!!descriptor'
   <td>...
  <tr>
   <td>'@media/resolution!!descriptor'
   <td>...
  <tr>
   <td>'@media/scan!!descriptor'
   <td>
    If the value is ''scan/progressive'': "<code>progressive</code>".
    If the value is ''scan/interlace'': "<code>interlace</code>".
  <tr>
   <td>'@media/grid!!descriptor'
   <td>...
</table>

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


Comparing Media Queries {#comparing-media-queries}
--------------------------------------------------

To
<dfn export>compare media queries</dfn>
<var>m1</var> and <var>m2</var> means to
<a lt="serialize a media query">serialize</a> them both and
return true if they are a
<a>case-sensitive</a> match and false if they
are not.


The {{MediaList}} Interface {#the-medialist-interface}
------------------------------------------------------

An object that implements the <code>MediaList</code> interface has an associated <dfn export for=MediaList>collection of media queries</dfn>.

<pre class=idl>
[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);
};
</pre>

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

<wpt>
  medialist-dynamic-001.html
  medialist-interfaces-001.html
  medialist-interfaces-002.html
  medialist-interfaces-004.html
  MediaList.html
  MediaList2.xhtml
</wpt>

To <dfn export>create a <code>MediaList</code> object</dfn> with a string <var>text</var>, run the following steps:
<ol>
 <li>Create a new <code>MediaList</code> object.
 <li>Set its {{MediaList/mediaText}} attribute to <var>text</var>.
 <li>Return the newly created <code>MediaList</code> object.
</ol>

The <dfn attribute for=MediaList>mediaText</dfn> attribute, on getting, must return a
<a lt="serialize a media query list">serialization</a> of the <a>collection of media queries</a>.
Setting the {{MediaList/mediaText}} attribute must run these steps:
<ol>
 <li>Empty the <a>collection of media queries</a>.
 <li>If the given value is the empty string, then return.
 <li>Append all the media queries as a result of <a lt="parse a media query list">parsing</a> the given
 value to the <a>collection of media queries</a>.
</ol>

The <dfn method for=MediaList>item(<var>index</var>)</dfn> method must return a
<a lt="serialize a media query">serialization</a> of the media query in the <a>collection of media queries</a>
given by <var>index</var>, or null, if <var>index</var> is greater than or equal to the number of media queries
in the <a>collection of media queries</a>.

The <dfn attribute for=MediaList>length</dfn> attribute must return the number of media queries in the <a>collection of media
queries</a>.

The <dfn method for=MediaList>appendMedium(<var>medium</var>)</dfn> method must run these steps:
<ol>
 <li>Let <var>m</var> be the result of <a lt="parse a media query">parsing</a> the given value.
 <li>If <var>m</var> is null, then return.
 <li>If <a lt="compare media queries">comparing</a> <var>m</var> with any of the media queries in the
 <a>collection of media queries</a> returns true, then return.
 <li>Append <var>m</var> to the <a>collection of media queries</a>.
</ol>

The <dfn method for=MediaList>deleteMedium(<var>medium</var>)</dfn> method must run these steps:
<ol>
 <li>Let <var>m</var> be the result of <a lt="parse a media query">parsing</a> the given value.
 <li>If <var>m</var> is null, then return.
 <li>Remove any media query from the <a>collection of media queries</a> for which
 <a lt="compare media queries">comparing</a> the media query with <var>m</var> returns true.
 If nothing was removed, then <a>throw</a> a {{NotFoundError}} exception.
</ol>

Selectors {#selectors}
======================

Selectors are defined in the Selectors specification. This section
mainly defines how to serialize them. <!-- XXX ref -->

<!-- XXX ref universal selector etc? some are in A some not -->


Parsing Selectors {#parsing-selectors}
--------------------------------------

To
<dfn export>parse a group of selectors</dfn>
means to parse the value using the <code>selectors_group</code>
production defined in the Selectors specification and return either a
group of selectors if parsing did not fail or null if parsing did
fail. <!-- XXX ref -->


Serializing Selectors {#serializing-selectors}
----------------------------------------------

<!-- http://dump.testsuite.org/2009/cssom/serializing-selectors.htm -->

To
<dfn export>serialize a group of selectors</dfn>
<a lt="serialize a selector">serialize</a> each selector in the
group of selectors and then
<a lt="serialize a comma-separated list">serialize</a> a
comma-separated list of these serializations.

To <dfn export>serialize a selector</dfn> let
<var>s</var> be the empty string, run the steps below for each
part of the chain of the selector, and finally return
<var>s</var>:

<ol>
 <li>If there is only one <a>simple selector</a> in the
 <a>compound selectors</a> which is a
 <a>universal selector</a>, append the result of
 <a lt="serialize a simple selector">serializing</a> the
 <a>universal selector</a> to <var>s</var>.

 <li>Otherwise, for each <a>simple selector</a> in the
 <a>compound selectors</a> that is not a
 universal selector of which the
 <a>namespace prefix</a> maps to a namespace that is not the
 <a>default namespace</a>
 <a lt="serialize a simple selector">serialize</a> the
 <a>simple selector</a> and append the result to
 <var>s</var>.

 <li>If this is not the last part of the chain of the selector append a
 single SPACE (U+0020), followed by the combinator
 "<code>></code>",
 "<code>+</code>",
 "<code>~</code>",
 "<code>>></code>",
 "<code>||</code>",
 as appropriate, followed by another single SPACE (U+0020) if the combinator was
 not whitespace, to <var>s</var>.

 <li>If this is the last part of the chain of the selector and there is
 a pseudo-element, append "<code>::</code>" followed by the name of the
 pseudo-element, to <var>s</var>.
</ol>

<wpt>
  selectorSerialize.html
  serialize-namespaced-type-selectors.html
</wpt>

To
<dfn export>serialize a simple selector</dfn>
let <var>s</var> be the empty string, run the steps below, and
finally return <var>s</var>:

<dl class="switch">
 <dt>type selector
 <dt>universal selector
 <dd>
  <ol>
   <li>If the <a>namespace prefix</a> maps to a namespace that is
   not the <a>default namespace</a> and is not the
   null namespace (not in a namespace) append the
   <a lt="serialize an identifier">serialization</a> of the
   <a>namespace prefix</a> as an identifier, followed by a
   "<code>|</code>" (U+007C) to <var>s</var>.

   <li>If the <a>namespace prefix</a> maps to a namespace that is
   the null namespace (not in a namespace) append
   "<code>|</code>" (U+007C) to <var>s</var>.
   <!-- This includes |* -->

   <li>If this is a type selector append the
   <a lt="serialize an identifier">serialization</a> of the element name
   as an identifier to <var>s</var>.

   <li>If this is a universal selector append "<code>*</code>" (U+002A)
   to <var>s</var>.
  </ol>


 <dt>attribute selector
 <dd>
  <ol>
   <li>Append "<code>[</code>" (U+005B) to
   <var>s</var>.

   <li>If the <a>namespace prefix</a> maps to a namespace that is
   not the null namespace (not in a namespace) append the
   <a lt="serialize an identifier">serialization</a> of the
   <a>namespace prefix</a> as an identifier, followed by a
   "<code>|</code>" (U+007C) to <var>s</var>.

   <li>Append the <a lt="serialize an identifier">serialization</a>
   of the attribute name as an identifier to <var>s</var>.

   <li>If there is an attribute value specified, append
   "<code>=</code>",
   "<code>~=</code>",
   "<code>|=</code>",
   "<code>^=</code>",
   "<code>$=</code>", or
   "<code>*=</code>"
   as appropriate (depending on the type of attribute selector), followed
   by the <a lt="serialize a string">serialization</a> of the
   attribute value as a string, to <var>s</var>.

   <li>If the attribute selector has the case-sensitivity flag present,
   append "<code> i</code>" (U+0020 U+0069) to <var>s</var>.

   <li>Append "<code>]</code>" (U+005D) to
   <var>s</var>.
  </ol>


 <dt>class selector
 <dd>Append a "<code>.</code>" (U+002E), followed by the
 <a lt="serialize an identifier">serialization</a> of the class name
 as an identifier to <var>s</var>.

 <dt>ID selector
 <dd>Append a "<code>#</code>" (U+0023), followed by the
 <a lt="serialize an identifier">serialization</a> of the ID
 as an identifier to <var>s</var>.

 <dt>pseudo-class
 <dd>
  If the pseudo-class does not accept arguments append
  "<code>:</code>" (U+003A), followed by the name of the pseudo-class, to
  <var>s</var>.

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

  <dl class="switch">
   <dt><code>:lang()</code>
   <dd>The <a lt="serialize a comma-separated list">serialization of a
   comma-separated list</a> of each argument's
   <a lt="serialize a string">serialization as a string</a>, preserving
   relative order.

   <dt><code>:nth-child()</code>
   <dt><code>:nth-last-child()</code>
   <dt><code>:nth-of-type()</code>
   <dt><code>:nth-last-of-type()</code>
   <dd>The result of serializing the value using the rules to <a>serialize an &lt;a-n-plus-b> value</a>.

   <dt><code>:not()</code>
   <dd>The result of serializing the value using the rules for
   <a lt="serialize a group of selectors">serializing a group of selectors</a>.
  </dl>

</dl>


CSS {#css-object-model}
=======================


CSS Style Sheets {#css-style-sheets}
------------------------------------

A <dfn export>CSS style sheet</dfn> is an abstract concept that
represents a style sheet as defined by the CSS specification. In the CSSOM a
<a>CSS style sheet</a> is represented as a {{CSSStyleSheet}} object.

<dl>
  <dt><dfn constructor for=CSSStyleSheet>CSSStyleSheet(<var>options</var>)</dfn></dt>
  <dd>
    When called, execute the steps to <a>create a constructed CSSStyleSheet</a> given <var>options</var> and return the result.
  </dd>

  <dt>To <dfn export>create a constructed {{/CSSStyleSheet}}</dfn></dt> given {{CSSStyleSheetInit}} <var>options</var>, run these steps:
  <dd>
    <ol>
      <li>Construct a new {{/CSSStyleSheet}} object <var>sheet</var>.</li>
      <li>Set <var>sheet</var>'s <a spec=cssom>location</a> to the <a spec=html for=/>base URL</a> of the <a>associated Document</a> for the <a>current global object</a>.
      <li>Set <var>sheet</var>'s <a>stylesheet base URL</a> to the {{CSSStyleSheetInit/baseURL}} attribute value from <var>options</var>.
      <li>Set <var>sheet</var>'s [=CSSStyleSheet/parent CSS style sheet=] to null.
      <li>Set <var>sheet</var>'s [=CSSStyleSheet/owner node=] to null.
      <li>Set <var>sheet</var>'s [=CSSStyleSheet/owner CSS rule=] to null.
      <li>Set <var>sheet</var>'s [=CSSStyleSheet/title=] to the empty string.
      <li>Unset <var>sheet</var>'s [=CSSStyleSheet/alternate flag=].
      <li>Set <var>sheet</var>'s [=CSSStyleSheet/origin-clean flag=].
      <li>Set <var>sheet</var>'s [=CSSStyleSheet/constructed flag=].
      <li>Set <var>sheet</var>'s [=CSSStyleSheet/Constructor document=] to the <a>associated Document</a> for the <a>current global object</a>.
      <li>If the {{CSSStyleSheetInit/media}} attribute of <var>options</var> is a string,
        <a>create a MediaList object</a> from the string
        and assign it as <var>sheet</var>'s [=CSSStyleSheet/media=].
        Otherwise, <a>serialize a media query list</a> from the attribute and then <a>create a MediaList object</a>
        from the resulting string and set it as <var>sheet</var>'s [=CSSStyleSheet/media=].
      <li>If the {{CSSStyleSheetInit/disabled}} attribute of <var>options</var> is true,
        set <var>sheet</var>'s [=CSSStyleSheet/disabled flag=].
      <li>Return <var>sheet</var>.
    </ol>
  </dd>
</dl>

<wpt>
  CSSStyleSheet-constructable-baseURL.html
  CSSStyleSheet-constructable-concat.html
  CSSStyleSheet-constructable-cssRules.html
  CSSStyleSheet-constructable-disabled-regular-sheet-insertion.html
  CSSStyleSheet-constructable-disallow-import.tentative.html
  CSSStyleSheet-constructable-duplicate.html
  CSSStyleSheet-constructable-insertRule-base-uri.html
  CSSStyleSheet-constructable-invalidation.html
  CSSStyleSheet-constructable-replace-cssRules.html
  CSSStyleSheet-constructable-replace-on-regular-sheet.html
  CSSStyleSheet-constructable.html
  CSSStyleSheet-modify-after-removal.html
  CSSStyleSheet-template-adoption.html
  CSSStyleSheet.html
  style-sheet-interfaces-001.html
  style-sheet-interfaces-002.html
</wpt>

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

<dl dfn-for="CSSStyleSheet">
 <dt><dfn id=concept-css-style-sheet-type>type</dfn>
 <dd>The literal string "<code>text/css</code>".

 <dt><dfn id=concept-css-style-sheet-location>location</dfn>
 <dd>Specified when created. The <a>absolute-URL string</a> of the first request of the
 <a>CSS style sheet</a> or null if the <a>CSS style sheet</a> was
 embedded. Does not change during the lifetime of the <a>CSS style sheet</a>.

 <dt><dfn id=concept-css-style-sheet-parent-css-style-sheet>parent CSS style sheet</dfn>
 <dd>Specified when created. The <a>CSS style sheet</a> that is the parent of the
 <a>CSS style sheet</a> or null if there is no associated parent.

 <dt><dfn id=concept-css-style-sheet-owner-node>owner node</dfn>
 <dd>Specified when created. The DOM node associated with the <a>CSS style sheet</a> or
 null if there is no associated DOM node.

 <dt><dfn id=concept-css-style-sheet-owner-css-rule>owner CSS rule</dfn>
 <dd>Specified when created. The <a for=/>CSS rule</a>
 in the <a for=CSSStyleSheet>parent CSS style sheet</a>
 that caused the inclusion of the <a>CSS style sheet</a> or null if
 there is no associated rule.

 <dt><dfn id=concept-css-style-sheet-media>media</dfn>
 <dd>
  Specified when created. The {{MediaList}} object associated with the
  <a>CSS style sheet</a>.

  If this property is specified to a string, the [=CSSStyleSheet/media=] must be set to the return value of invoking
  <a>create a <code>MediaList</code> object</a> steps for that string.

  If this property is specified to an attribute of the <a for=CSSStyleSheet>owner node</a>, the
  [=CSSStyleSheet/media=] must be set to the return value of invoking <a>create a <code>MediaList</code> object</a> steps
  for the value of that attribute. Whenever the attribute is set, changed or removed, the [=CSSStyleSheet/media=]'s
  {{MediaList/mediaText}} attribute must be set to the new value of the attribute, or to null if the attribute is absent.

  Note: Changing the [=CSSStyleSheet/media=]'s {{MediaList/mediaText}} attribute does not
  change the corresponding attribute on the <a for=CSSStyleSheet>owner node</a>.

  Note: The <a for=CSSStyleSheet>owner node</a> of a <a>CSS style sheet</a>, if non-null, is the node whose <a>associated
  CSS style sheet</a> is the <a>CSS style sheet</a> in question, when the <a>CSS style sheet</a> is <a
  lt="add a CSS style sheet">added</a>.


 <dt><dfn id=concept-css-style-sheet-title>title</dfn>
 <dd>
  Specified when created. The title of the <a>CSS style sheet</a>, which can be the empty string.

  <div class="example">
   In the following, the <a>title</a> is non-empty
   for the first style sheet, but is empty for the second and third style sheets.

   <pre>
   &lt;style title="papaya whip">
     body { background: #ffefd5; }
   &lt;/style>
   </pre>

   <pre>
   &lt;style title="">
     body { background: orange; }
   &lt;/style>
   </pre>

   <pre>
   &lt;style>
     body { background: brown; }
   &lt;/style>
   </pre>
  </div>

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

  Note: HTML only <a href="https://html.spec.whatwg.org/#the-style-element:concept-css-style-sheet-title">specifies</a>
  <a>title</a> to be an attribute of the <a for=CSSStyleSheet>owner node</a>
  if the node is in <a>in a document tree</a>.


 <dt><dfn id=concept-css-style-sheet-alternate-flag>alternate flag</dfn>
 <dd>
  Specified when created. Either set or unset. Unset by default.

  <div class="example">
   The following <a>CSS style sheets</a> have
   their <a>alternate flag</a> set:

   <pre>&lt;?xml-stylesheet alternate="yes" title="x" href="data:text/css,&hellip;"?></pre>

   <pre>&lt;link rel="alternate stylesheet" title="x" href="data:text/css,&hellip;"></pre>
  </div>


 <dt><dfn id=concept-css-style-sheet-disabled-flag>disabled flag</dfn>
 <dd>
  Either set or unset. Unset by default.

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



 <dt><dfn id=concept-css-style-sheet-css-rules>CSS rules</dfn>
 <dd>The CSS rules associated with the
 <a>CSS style sheet</a>.

 <dt><dfn id=concept-css-style-sheet-origin-clean-flag>origin-clean flag</dfn>
 <dd>Specified when created. Either set or unset. If it is set, the API allows reading and modifying of the <a for=CSSStyleSheet>CSS rules</a>.

 <dt><dfn id=concept-css-style-sheet-constructed-flag>constructed flag</dfn></dt>
 <dd>Specified when created. Either set or unset. Unset by default.
 Signifies whether this stylesheet was created by invoking the IDL-defined constructor.

 <dt><dfn id=concept-css-style-sheet-disallow-modification-flag>disallow modification flag</dfn></dt>
 <dd>Either set or unset. Unset by default. If set, modification of the stylesheet's rules is not allowed.

 <dt><dfn id=concept-css-style-sheet-constructor-document>constructor document</dfn></dt>
 <dd>Specified when created. The {{Document}} a constructed stylesheet is associated with. Null by default.
 Only non-null for stylesheets that have <a>constructed flag</a> set.

 <dt><dfn id=concept-css-style-sheet-stylesheet-base-url>stylesheet base URL</dfn></dt>
 <dd>The base URL to use when resolving relative URLs in the stylesheet. Null by default.
 Only non-null for stylesheets that have <a>constructed flag</a> set.

</dl>

<wpt>
  base-uri.html
</wpt>

### The {{StyleSheet}} Interface ### {#the-stylesheet-interface}

The {{StyleSheet}} interface represents an abstract, base style sheet.

<pre class=idl>
[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;
};
</pre>

The <dfn attribute for=StyleSheet>type</dfn> attribute must return the <a for=CSSStyleSheet>type</a>.

The <dfn attribute for=StyleSheet>href</dfn> attribute must return the <a>location</a>.

The <dfn attribute for=StyleSheet>ownerNode</dfn> attribute must return the <a for=CSSStyleSheet>owner node</a>.

The <dfn attribute for=StyleSheet>parentStyleSheet</dfn> attribute must return the
<a for=CSSStyleSheet>parent CSS style sheet</a>.

The <dfn attribute for=StyleSheet>title</dfn> attribute must return the <a>title</a> or null if
<a>title</a> is the empty string.

The <dfn attribute for=StyleSheet>media</dfn> attribute must return the [=CSSStyleSheet/media=].

The <dfn attribute for=StyleSheet>disabled</dfn> attribute, on getting, must return true if the
<a>disabled flag</a>
is set, or false otherwise. On setting, the {{StyleSheet/disabled}} attribute must set the
<a>disabled flag</a> if the new value is true, or unset the
<a>disabled flag</a> otherwise.

<wpt>
  link-element-stylesheet-title.html
  stylesheet-same-origin.sub.html
  stylesheet-title.html
</wpt>

### The {{CSSStyleSheet}} Interface ### {#the-cssstylesheet-interface}

The {{CSSStyleSheet}} interface represents a <a>CSS style sheet</a>.

<pre class=idl>
[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&lt;CSSStyleSheet> replace(USVString text);
  undefined replaceSync(USVString text);
};

dictionary CSSStyleSheetInit {
  DOMString? baseURL = null;
  (MediaList or DOMString) media = "";
  boolean disabled = false;
};
</pre>

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

The <dfn attribute for=CSSStyleSheet>cssRules</dfn> attribute must follow these steps:

<ol>
 <li>If the <a>origin-clean flag</a> is unset,
 <a>throw</a> a {{SecurityError}} exception.
 <li>Return a read-only, live {{CSSRuleList}} object representing
 the <a for=CSSStyleSheet>CSS rules</a>.

 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 {{CSSStyleSheet/insertRule()}} or {{CSSStyleSheet/deleteRule()}} methods can result in
 mutations reflected in the returned object.

</ol>

The <dfn method for=CSSStyleSheet>insertRule(<var>rule</var>, <var>index</var>)</dfn> method must run the following steps:

<ol>
 <li>If the <a>origin-clean flag</a> is unset,
 <a>throw</a> a {{SecurityError}} exception.
 <li>If the <a>disallow modification flag</a> is set, throw a {{NotAllowedError}} {{DOMException}}.
 <li>Let <var>parsed rule</var> be the return value of invoking <a>parse a rule</a> with <var>rule</var>.
 <li>If <var>parsed rule</var> is a syntax error, throw a {{SyntaxError}} {{DOMException}}.
 <li>If <var>parsed rule</var> is an <a>@import</a> rule, and the <a>constructed flag</a> is set, throw
 a {{SyntaxError}} {{DOMException}}.
 <li>Return the result of invoking <a>insert a CSS rule</a> <var>rule</var> in the <a for=CSSStyleSheet>CSS rules</a>
 at <var>index</var>.
</ol>

<wpt>
  insert-dir-rule-crash.html
  insert-dir-rule-in-iframe-crash.html
  insert-invalid-where-rule-crash.html
  insertRule-across-context.html
  insertRule-charset-no-index.html
  insertRule-from-script.html
  insertRule-import-no-index.html
  insertRule-import-no-sheet-crash.html
  insertRule-import-trailing-garbage-crash.html
  insertRule-namespace-no-index.html
  insertRule-no-index.html
  insertRule-syntax-error-01.html
</wpt>

The <dfn method for=CSSStyleSheet>deleteRule(<var>index</var>)</dfn> method must run the following steps:

<ol>
 <li>If the <a>origin-clean flag</a> is unset,
 <a>throw</a> a {{SecurityError}} exception.
 <li>If the <a>disallow modification flag</a> is set, throw a {{NotAllowedError}} {{DOMException}}.
 <li><a>Remove a CSS rule</a> in the <a for=CSSStyleSheet>CSS rules</a> at <var>index</var>.
</ol>

The <dfn method for=CSSStyleSheet>replace(<a for=CSSRule>text</a>)</dfn> method must run the following steps:
<ol>
 <li>Let <var>promise</var> be a promise.
 <li>If the <a>constructed flag</a> is not set, or the <a>disallow modification flag</a> is set, reject <var>promise</var> with a
 {{NotAllowedError}} {{DOMException}} and return <var>promise</var>.
 <li>Set the <a>disallow modification flag</a>.
 <li><a>In parallel</a>, do these steps:
 <ol>
   <li>Let <var>rules</var> be the result of running <a>parse a stylesheet's contents</a> from <var>text</var>.
   <li>If <var>rules</var> contains one or more <a>@import</a> rules, <a lt="remove a CSS rule">remove those rules</a> from <var>rules</var>.
   <li>Set <var>sheet</var>'s <a>CSS rules</a> to <var>rules</var>.
   <li>Unset <var>sheet</var>'s <a>disallow modification flag</a>.
   <li>Resolve <var>promise</var> with <var>sheet</var>.
 </ol>
 <li>Return <var>promise</var>.
</ol>

The <dfn method for=CSSStyleSheet>replaceSync(<a for=CSSRule>text</a>)</dfn> method must run the
steps to <a>synchronously replace the rules of a CSSStyleSheet</a> on this {{CSSStyleSheet}} given <var>text</var>.

To <dfn export>synchronously replace the rules of a CSSStyleSheet</dfn> on <var>sheet</var> given <var>text</var>, run these steps:
<ol>
 <li>If the <a>constructed flag</a> is not set, or the <a>disallow modification flag</a> is set, throw a {{NotAllowedError}}
 {{DOMException}}.
 <li>Let <var>rules</var> be the result of running <a>parse a stylesheet's contents</a> from <var>text</var>.
 <li>If <var>rules</var> contains one or more <a>@import</a> rules, <a lt="remove a CSS rule">remove those rules</a> from <var>rules</var>.
 <li>Set <var>sheet</var>'s <a>CSS rules</a> to <var>rules</var>.
</ol>

#### Deprecated CSSStyleSheet members #### {#legacy-css-style-sheet-members}

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

<pre class=idl>
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);
};
</pre>

The <dfn attribute for=CSSStyleSheet>rules</dfn> attribute must follow the same steps as {{CSSStyleSheet/cssRules}}, and return the same object {{CSSStyleSheet/cssRules}} would return.

The <dfn method for=CSSStyleSheet>removeRule(<var>index</var>)</dfn> method must run the same steps as {{CSSStyleSheet/deleteRule()}}.

The <dfn method for=CSSStyleSheet>addRule(<var>selector</var>, <var>block</var>, <var>optionalIndex</var>)</dfn> method must run the following steps:

<ol>
 <li>Let <var>rule</var> be an empty string.
 <li>Append <var>selector</var> to <var>rule</var>.
 <li>Append <code>" { "</code> to <var>rule</var>.
 <li>If <var>block</var> is not empty, append <var>block</var>, followed by a space, to <var>rule</var>.
 <li>Append <code>"}"</code> to <var>rule</var>
 <li>Let <var>index</var> be <var>optionalIndex</var> if provided, or the number of <a for=CSSStyleSheet>CSS rules</a> in the stylesheet otherwise.
 <li>Call {{CSSStyleSheet/insertRule()}}, with <var>rule</var> and <var>index</var> as arguments.
 <li>Return <code>-1</code>.
</ol>

<p class=advisement>
  Authors should not use these members
  and should instead use and teach the standard {{CSSStyleSheet}} interface defined earlier,
  which is consistent with {{CSSGroupingRule}}.
</p>

<wpt>
  removerule-invalidation-crash.html
</wpt>

CSS Style Sheet Collections {#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 <a>CSS style sheets</a>, named the
<dfn export for=DocumentOrShadowRoot>document or shadow root CSS style sheets</dfn>. This is
an ordered list that contains:
<ol>
  <li>Any <a>CSS style sheets</a> created from HTTP <code>Link</code> headers, in header order</li>
  <li>Any <a>CSS style sheets</a> associated with the {{DocumentOrShadowRoot}}, in <a>tree order</a></li>
</ol>

Each {{DocumentOrShadowRoot}} has an associated list of zero or more <a>CSS style sheets</a>, named the
<dfn export for=DocumentOrShadowRoot>final CSS style sheets</dfn>. This is
an ordered list that contains:
<ol>
  <li>The <a>document or shadow root CSS style sheets</a>.</li>
  <li>The contents of {{DocumentOrShadowRoot}}'s {{DocumentOrShadowRoot/adoptedStyleSheets}}'
  [=observable array attribute/backing list=], in array order.</li>
</ol>

To <dfn export>create a CSS style sheet</dfn>, run these steps:

<ol>
 <li>Create a new <a>CSS style sheet</a> object and set its
 properties as specified.

 <li>
  Then run the <a>add a CSS style sheet</a> steps for the newly created <a>CSS style sheet</a>.

  <p class=warning>If the <a>origin-clean flag</a> is unset, this can expose information from the user's
  intranet.
</ol>

To <dfn export>add a CSS style sheet</dfn>, run these
steps:

<ol>
 <li>Add the <a>CSS style sheet</a> to the list of
 <a>document or shadow root CSS style sheets</a> at the appropriate location.

 <li>
  <p>If the <a>CSS style sheet</a>'s <a for=CSSStyleSheet>owner node</a> <a>contributes a
 script-blocking style sheet</a>, then user agents must <a for=list>append</a> the <a
 for=CSSStyleSheet>owner node</a> to its <a>node document</a>'s <a for=Document>script-blocking
 style sheet set</a>.</p>
 <p class="note">The remainder of these steps deal with the <a>disabled flag</a>.</p>

 <li>If the <a>disabled flag</a> is set, then return.

 <li>If the <a>title</a> is not the empty string, the
 <a>alternate flag</a> is unset, and
 <a>preferred CSS style sheet set name</a> is the empty string
 <a>change the preferred CSS style sheet set name</a> to the
 <a>title</a>.

 <li>
  If any of the following is true, then unset the
  <a>disabled flag</a> and return:

  <ul>
   <li>The <a>title</a> is the empty string.
   <li>The <a>last CSS style sheet set name</a> is null and the
   <a>title</a> is a
   <a>case-sensitive</a> match
   for the <a>preferred CSS style sheet set name</a>.
   <li>The <a>title</a> is a
   <a>case-sensitive</a> match for the
   <a>last CSS style sheet set name</a>.
  </ul>


 <li>Set the <a>disabled flag</a>.
</ol>

<wpt>
  preferred-stylesheet-order.html
  preferred-stylesheet-reversed-order.html
</wpt>

To <dfn export>remove a CSS style sheet</dfn>, run these steps:

<ol>
 <li>Remove the <a>CSS style sheet</a> from the list of <a>document or shadow root CSS style sheets</a>.

 <li>Set the <a>CSS style sheet</a>'s <a for=CSSStyleSheet>parent CSS style sheet</a>,
 <a for=CSSStyleSheet>owner node</a> and <a for=CSSStyleSheet>owner CSS rule</a> to null.

 <!-- "associated CSS style sheet" is defined in terms of owner node, so we don't need to set it to null explicitly -->

 <!-- XXX does anything need to happen wrt alternate style sheets? what if the last style sheet with the preferred style sheet set name is removed? -->
</ol>

<wpt>
  delete-namespace-rule-when-child-rule-exists.html
</wpt>

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

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

A <dfn export>CSS style sheet set name</dfn> is the
<a>title</a> the <a>CSS style sheet set</a> has in
common.

An <dfn export>enabled CSS style sheet set</dfn> is a
<a>CSS style sheet set</a> of which each <a>CSS style sheet</a> has
its <a>disabled flag</a> unset.

To <dfn export>enable a CSS style sheet set</dfn>
with name <var>name</var>, run these steps:

<ol>
 <li>If <var>name</var> is the empty string, set the
 <a>disabled flag</a> for each <a>CSS style sheet</a>
 that is in a <a>CSS style sheet set</a> and return.

 <li>Unset the <a>disabled flag</a> for each
 <a>CSS style sheet</a> in a <a>CSS style sheet set</a> whose
 <a>CSS style sheet set name</a> is a
 <a>case-sensitive</a> match for
 <var>name</var> and set it for all other
 <a>CSS style sheets</a> in a
 <a>CSS style sheet set</a>.
</ol>

To <dfn export>select a CSS style sheet set</dfn>
with name <var>name</var>, run these steps:

<ol>
 <li><a>enable a CSS style sheet set</a> with name
 <var>name</var>.

 <li>Set <a>last CSS style sheet set name</a> to
 <var>name</var>.
</ol>

A <dfn export>last CSS style sheet set name</dfn>
is a concept to determine what <a>CSS style sheet set</a> was last
<a lt="select a CSS style sheet set">selected</a>. Initially its
value is null.

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

To
<dfn export>change the preferred CSS style sheet set name</dfn>
with name <var>name</var>, run these steps:

<ol>
 <li>Let <var>current</var> be the <a>preferred CSS style sheet set name</a>.

 <li>Set <a>preferred CSS style sheet set name</a> to
 <var>name</var>.

 <li>If <var>name</var> is not a
 <a>case-sensitive</a> match for
 <var>current</var> and
 <a>last CSS style sheet set name</a> is null
 <a>enable a CSS style sheet set</a> with name
 <var>name</var>.
</ol>

<!-- XXX ought to define "applied"

thoughts:
  depends on disabled flag, alternate flag, media queries, sheesh
 -->


### The HTTP Default-Style Header ### {#the-http-default-style-header}

The HTTP <a lt="http-default-style">Default-Style</a> header
can be used to set the <a>preferred CSS style sheet set name</a>
influencing which <a>CSS style sheet set</a> is (initially) the
<a>enabled CSS style sheet set</a>.

For each HTTP <a lt="http-default-style">Default-Style</a>
header, in header order, the user agent must
<a>change the preferred CSS style sheet set name</a> with name being the
value of the header.


### The {{StyleSheetList}} Interface ### {#the-stylesheetlist-interface}

The {{StyleSheetList}} interface represents an ordered collection of <a>CSS style sheets</a>.

<pre class=idl>
[Exposed=Window]
interface StyleSheetList {
  getter CSSStyleSheet? item(unsigned long index);
  readonly attribute unsigned long length;
};
</pre>

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

The <dfn method for=StyleSheetList>item(<var>index</var>)</dfn> method must return the <var>index</var>th <a>CSS style
sheet</a> in the collection. If there is no <var>index</var>th object in the collection, then the method must return null.

The <dfn attribute for=StyleSheetList>length</dfn> attribute must return the number of <a>CSS style sheets</a>
represented by the collection.

<wpt>
  StyleSheetList-constructable-with-style-recalc.html
  StyleSheetList-constructable.html
  StyleSheetList.html
</wpt>

### Extensions to the {{DocumentOrShadowRoot}} Interface Mixin ### {#extensions-to-the-document-or-shadow-root-interface}

<pre class=idl>
partial interface mixin DocumentOrShadowRoot {
  [SameObject] readonly attribute StyleSheetList styleSheets;
  attribute ObservableArray&lt;CSSStyleSheet> adoptedStyleSheets;
};
</pre>

The <dfn attribute for=DocumentOrShadowRoot>styleSheets</dfn> attribute must return a {{StyleSheetList}} collection representing
the <a>document or shadow root CSS style sheets</a>.

The [=observable array attribute/set an indexed value=] algorithm for
<dfn attribute for="DocumentOrShadowRoot"><code>adoptedStyleSheets</code></dfn>, given <var>value</var> and <var>index</var>,
is the following:
<ol>
  <li>If <var>value</var>'s <a>constructed flag</a> is not set, or its <a>constructor document</a> is not equal to this
  {{DocumentOrShadowRoot}}'s <a>node document</a>, throw a "{{NotAllowedError}}" {{DOMException}}.</li>
</ol>

<wpt>
  adoptedstylesheets-modify-array-and-sheet.html
  adoptedstylesheets-observablearray.html
  ttwf-cssom-doc-ext-load-count.html
  ttwf-cssom-doc-ext-load-tree-order.html
  ttwf-cssom-document-extension.html
</wpt>

Style Sheet Association {#style-sheet-association}
--------------------------------------------------

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


### Fetching CSS style sheets ### {#fetching-css-style-sheets}

<div algorithm>
 To <dfn export>fetch a CSS style sheet</dfn>
 with parsed URL <var>parsed URL</var>,
 referrer <var>referrer</var>,
 document <var>document</var>,
 optionally a set of parameters <var>parameters</var>
 (used as input to creating a <a>request</a>),
 and an algorithm for handling the response result <var>processTheResponse</var> that takes a response,
 follow these steps:

 <ol>
  <li>Let <var>origin</var> be <var>document</var>'s <a for=/>origin</a>.

  <li>Let <var>request</var> be a new <a>request</a>, with the
  <a for=request>url</a> <var>parsed URL</var>,
  <a for=request>origin</a> <var>origin</var>,
  <a for=request>referrer</a> <var>referrer</var>, and if specified the set of parameters <var>parameters</var>.

  <li><a>Fetch</a> <var>request</var>,
   with <var ignore>processResponseEndOfBody</var>, given <var>response</var>,
   being the following steps:

   <ol>
    <li>If <var>response</var> is a <a>network error</a>, return.

    <li>If <var>document</var> is in <a>quirks mode</a>, <var>response</var> is
    <a>CORS-same-origin</a> and the <a>Content-Type metadata</a> of <var>response</var> is not a
    <a>supported styling language</a> change the <a>Content-Type metadata</a> of <var>response</var> to
    <code>text/css</code>.

    <li>If <var>response</var> is not in a <a>supported styling language</a>, return.

    <li>Execute <var>processTheResponse</var> given <var>response</var>
   </ol>
 </ol>
</div>

### The {{LinkStyle}} Interface ### {#the-linkstyle-interface}

The <dfn export>associated CSS style sheet</dfn> of a node is the <a>CSS style sheet</a> in the list of
<a>document or shadow root CSS style sheets</a> of which the <a for=CSSStyleSheet>owner node</a> is said node.
This node must also implement the {{LinkStyle}} interface.

<pre class=idl>
interface mixin LinkStyle {
  readonly attribute CSSStyleSheet? sheet;
};
</pre>

The <dfn attribute for=LinkStyle>sheet</dfn> attribute must return the <a>associated CSS style sheet</a> for the node or null
if there is no <a>associated CSS style sheet</a>.

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

 <pre>
 &lt;style type="text/css"&gt;
   body { background:lime }
 &lt;/style&gt;
 </pre>
 <pre>
 &lt;style type="text/example-sheets"&gt;
   $(body).background := lime
 &lt;/style&gt;
 </pre>
</div>

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

<wpt>
  HTMLLinkElement-disabled-001.html
  HTMLLinkElement-disabled-002.html
  HTMLLinkElement-disabled-003.html
  HTMLLinkElement-disabled-004.html
  HTMLLinkElement-disabled-005.html
  HTMLLinkElement-disabled-006.html
  HTMLLinkElement-disabled-007.html
  HTMLLinkElement-disabled-alternate.html
  HTMLLinkElement-load-event-002.html
  HTMLLinkElement-load-event.html
  HTMLStyleElement-load-event.html
</wpt>

### Requirements on specifications ### {#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 <a>CSS style sheet</a> is
<a lt="create a CSS style sheet">created</a>.


### Requirements on user agents Implementing the xml-stylesheet processing instruction ### {#requirements-on-user-agents-implementing-the-xml-stylesheet-processing-instruction}

<!-- XXX load/error events -->

<pre class="idl">ProcessingInstruction includes LinkStyle;</pre>

The <dfn>prolog</dfn> refers to <a>nodes</a> that are children of the
{{Document}} and are not <a>following</a> the
{{Element}} child of the {{Document}}, if any.


<div algorithm="handle a PI stylesheet">
 When a <code>ProcessingInstruction</code> <a>node</a> <var>node</var> becomes part of the
 <a>prolog</a>, is no longer part of the <a>prolog</a>, or has its <a spec=dom>data</a> changed, these steps
 must be run:

 <ol>
  <li>If an instance of this algorithm is currently running for <var>node</var>, abort that instance, and stop the associated
  <a>fetching</a> if applicable.

  <li>If <var>node</var> has an <a>associated CSS style sheet</a>, <a lt="remove a CSS style sheet">remove</a> it.

  <li>If <var>node</var> is not an <a>xml-stylesheet processing instruction</a>, then return.

  <li>If <var>node</var> does not have an <code>href</code> <a>pseudo-attribute</a>, then return.

  <li>Let <var>title</var> be the value of the
  <code>title</code> <a>pseudo-attribute</a> or the empty string if the
  <code>title</code> <a>pseudo-attribute</a> is not specified.

  <li>If there is an <code>alternate</code> <a>pseudo-attribute</a>
  whose value is a <a>case-sensitive</a> match
  for "<code>yes</code>" and <var>title</var> is the
  empty string, then return.

  <li>If there is a <code>type</code> <a>pseudo-attribute</a> whose
  value is not a <a>supported styling language</a> the user agent
  may return.

  <li>Let <var>input URL</var> be the value specified by the
  <code>href</code> <a>pseudo-attribute</a>.

  <li>Let <var>document</var> be <var>node</var>'s <a>node document</a>

  <li>Let <var>base URL</var> be <var>document</var>'s <a>document base URL</a>.

  <li>Let <var>referrer</var> be <var>document</var>'s <a lt="document URL">address</a>.

  <li>Let <var>parsed URL</var> be the return value of invoking the <a>URL parser</a> with the
  string <var>input URL</var> and the base URL <var>base URL</var>.

  <li>If <var>parsed URL</var> is failure, then return.

  <li>[=Fetch a CSS style sheet=]
   with parsed URL <var>parsed URL</var>,
   referrer <var>referrer</var>,
   document <var>document</var>,
   and <var ignore>processTheResponse</var> given |response| being the following steps:

   <ol>
    <li>
     <a>Create a CSS style sheet</a> with the following properties:

     <dl>
      <dt><a>location</a>
      <dd>The result of invoking the <a>URL serializer</a> with <var>parsed URL</var>.

      <dt><a for=CSSStyleSheet>parent CSS style sheet</a>
      <dd>null.

      <dt><a for=CSSStyleSheet>owner node</a>
      <dd><var>node</var>.

      <dt><a for=CSSStyleSheet>owner CSS rule</a>
      <dd>null.

      <dt>[=CSSStyleSheet/media=]
      <dd>The value of the <code>media</code> <a>pseudo-attribute</a>
      if any, or the empty string otherwise.

      <dt><a>title</a>
      <dd><var>title</var>.

      <dt><a>alternate flag</a>
      <dd>Set if the <code>alternate</code> <a>pseudo-attribute</a>
      value is a <a>case-sensitive</a> match for
      "<code>yes</code>", or unset otherwise.

      <dt><a>origin-clean flag</a>
      <dd>Set if <var>response</var> is <a>CORS-same-origin</a>, or unset otherwise.
     </dl>

     The CSS <a>environment encoding</a> is the result of running the following steps:

     <ol>
      <li>If the element has a <code>charset</code>
      <a>pseudo-attribute</a>,
      <a>get an encoding</a> from that pseudo-attribute's value.
      If that succeeds, return the resulting encoding and abort these steps.

      <li>Otherwise, return the <a lt="encoding" for="Document">document's character encoding</a>.
      [[!DOM]]
     </ol>
   </ol>
 </ol>
</div>

### Requirements on user agents Implementing the HTTP Link Header ### {#requirements-on-user-agents-implementing-the-http-link-header}

<!-- XXX ref, one day -->

<!-- XXX deal with media param -->

<p class=atrisk>For each HTTP <code>Link</code> header of which one
of the link relation types is an
<a>ASCII case-insensitive</a> match
for "<code>stylesheet</code>" these steps
must be run:

<div algorithm="fetch a Link header stylesheet">
 <ol>
  <li>Let <var>title</var> be the value of the first of all the
  <code>title</code> parameters.
  If there are no such parameters it is the empty string.

  <li>If one of the (other) link relation types is an
  <a>ASCII case-insensitive</a> match for
  "<code>alternate</code>" and <var>title</var> is the
  empty string, then return.

  <li>Let <var>input URL</var> be the value specified.

  Issue: Be more specific

  <li>Let <var>base URL</var> be the document's <a>document base URL</a>.

  Issue: Is there a document at this point?

  <li>Let <var>referrer</var> be the document's <a lt="document URL">address</a>.

  <!--<li>Let <var>origin</var> be the document's <a for=/>origin</a>.-->

  <li>Let <var>parsed URL</var> be the return value of invoking the <a>URL parser</a> with the
  string <var>input URL</var> and the base URL <var>base URL</var>.

  <li>If <var>parsed URL</var> is failure, then return.

  <li>[=Fetch a CSS style sheet=]
   with parsed URL <var>parsed URL</var>,
   referrer <var>referrer</var>,
   document being the document,
   and <var ignore>processTheResponse</var>, given |response|, being the following steps:

   Issue: What if the HTML parser hasn't decided on quirks/non-quirks yet?

   <ol>
    <li>
     <a>Create a CSS style sheet</a> with the following properties:

     <dl>
      <dt><a>location</a>
      <dd>The result of invoking the <a>URL serializer</a> with <var>parsed URL</var>.

      <dt><a for=CSSStyleSheet>owner node</a>
      <dd>null.

      <dt><a for=CSSStyleSheet>parent CSS style sheet</a>
      <dd>null.

      <dt><a for=CSSStyleSheet>owner CSS rule</a>
      <dd>null.

      <dt>[=CSSStyleSheet/media=]
      <dd>The value of the first <code>media</code> parameter.
      <!-- XXX register media parameter? bah -->

      <dt><a>title</a>
      <dd><var>title</var>.

      <dt><a>alternate flag</a>
      <dd>Set if one of the specified link relation type for this HTTP
       <code>Link</code> header is an
       <a>ASCII case-insensitive</a> match for
       "<code>alternate</code>", or false otherwise.

      <dt><a>origin-clean flag</a>
      <dd>Set if <var>response</var> is <a>CORS-same-origin</a>, or unset otherwise.
     </dl>
   </ol>
 </ol>
</div>

A style sheet referenced by a HTTP <code>Link</code> header using the rules in this section is said to be <a>a style sheet
that is blocking scripts</a> 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.

CSS Rules {#css-rules}
----------------------

A <dfn export>CSS rule</dfn> is an abstract concept that
denotes a rule as defined by the CSS specification. A
<a for=/>CSS rule</a> is represented as an object that implements a subclass of
the {{CSSRule}} interface, and which has the following
associated state items:

<dl dfn-for="CSSRule">
<dt><dfn id=concept-css-rule-type>type</dfn>
<dd>A non-negative integer associated with a particular type of rule.
This item is initialized when a rule is created and cannot change.

<dt><dfn id=concept-css-rule-text>text</dfn>
<dd>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.

<dt><dfn id=concept-css-rule-parent-css-rule>parent CSS rule</dfn>
<dd>A reference to an enclosing <a for=/>CSS rule</a> 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.

<dt><dfn id=concept-css-rule-parent-css-style-sheet>parent CSS style sheet</dfn>
<dd>A reference to a parent <a>CSS style sheet</a> or null.
This item is initialized to reference an associated style sheet when the rule is created. It can be changed to null.

<dt><dfn export id=concept-css-rule-child-css-rules>child CSS rules</dfn>
<dd>A list of child <a for=/>CSS rules</a>. The list can be mutated.
</dl>

In addition to the above state, each <a for=/>CSS rule</a> may be associated
with other state in accordance with its <a for=CSSRule>type</a>.

To <dfn export>parse a CSS rule</dfn> from a string <var>string</var>, run the following steps:

<ol>
 <li>Let <var>rule</var> be the return value of invoking <a>parse a rule</a> with <var>string</var>.
 <li>If <var>rule</var> is a syntax error, return <var>rule</var>.
 <li>Let <var>parsed rule</var> be the result of parsing <var>rule</var> according to the appropriate CSS specifications, dropping parts that are said to be
 ignored. If the whole <var>rule</var> is dropped, return a syntax error.
 <li>Return <var>parsed rule</var>.
</ol>

To <dfn export>serialize a CSS rule</dfn>, perform one of the following in accordance with the <a for=/>CSS rule</a>'s
<a for=CSSRule>type</a>:

<dl class="switch">
 <dt>{{CSSStyleRule}}
 <dd>
  Return the result of the following steps:

  <ol>
    <li>Let |s| initially be
        the result of performing <a>serialize a group of selectors</a> on the rule's associated selectors,
        followed by the string "<code> {</code>", i.e., a single SPACE (U+0020), followed by LEFT CURLY BRACKET (U+007B).
    <li>Let |decls| be the result of performing <a>serialize a CSS declaration block</a> on the rule's associated declarations, or null if there are no such declarations.
    <li>Let |rules| be the result of performing [=serialize a CSS rule=] on each rule in the rule's {{CSSStyleRule/cssRules}} list, or null if there are no such rules.
    <li>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|.
    <li>If |rules| is null:
        <ol>
            <li>Append a single SPACE (U+0020) to |s|
            <li>Append |decls| to |s|
            <li>Append " }" to |s| (i.e. a single SPACE (U+0020) followed by RIGHT CURLY BRACKET (U+007D)).
            <li>Return |s|.
        </ol>
    <li>Otherwise:
        <ol>
            <li>If |decls| is not null, prepend it to |rules|.
            <li>For each |rule| in |rules|:
                <ul>
                    <li>If |rule| is the empty string, do nothing.
                    <li>Otherwise:
                        <ol>
                            <li>Append a newline followed by two spaces to |s|.
                            <li>Append |rule| to |s|.
                        </ol>
                </ul>
            <li>Append a newline followed by RIGHT CURLY BRACKET (U+007D) to |s|.
            <li>Return |s|.
        </ol>
      </li>
  </ol>
 </dd>

 <dt>{{CSSImportRule}}
 <dd>
  The result of concatenating the following:
  <ol>
   <li>The string "<code>@import</code>" followed by a single SPACE (U+0020).
   <li>The result of performing <a>serialize a URL</a> on the rule's location.
   <li>If the rule's associated media list is not empty, a single SPACE (U+0020) followed by the
   result of performing <a>serialize a media query list</a> on the media list.
   <li>The string "<code>;</code>", i.e., SEMICOLON (U+003B).
  </ol>
  <div class="example">
  <pre>@import url("import.css");</pre>
  <pre>@import url("print.css") print;</pre>
  </div>


 <dt>{{CSSMediaRule}}
 <dd>
  The result of concatenating the following:
  <ol>
   <li>The string "<code>@media</code>", followed by a single SPACE (U+0020).</li>
   <li>The result of performing <a>serialize a media query list</a> on rule's media query list.</li>
   <li>A single SPACE (U+0020), followed by the string "{", i.e., LEFT CURLY BRACKET (U+007B), followed by a newline.</li>
   <li>The result of performing <a>serialize a CSS rule</a> on each rule in the rule's {{CSSGroupingRule/cssRules}} list,
   filtering out empty strings, indenting each item with two spaces, all joined with newline.</li>
   <li>A newline, followed by the string "}", i.e., RIGHT CURLY BRACKET (U+007D)</li>
  </ol>

 <dt>{{CSSFontFaceRule}}
 <dd>
  The result of concatenating the following:
  <ol>
   <li>The string "<code>@font-face {</code>".</li>
   <li>If the '@font-face/font-family' descriptor is present:
    <ol>
      <li>A single SPACE (U+0020), followed by the string "<code>font-family:</code>", followed by a single SPACE (U+0020).</li>
      <li>The result of performing <a>serialize a string</a> on the rule’s font family name.</li>
      <li>The string "<code>;</code>", i.e., SEMICOLON (U+003B).</li>
    </ol>
   </li>
   <li>
    If the rule's associated source list is not empty, follow these substeps:
    <ol>
     <li>A single SPACE (U+0020), followed by the string "<code>src:</code>", followed by a single
     SPACE (U+0020).</li>

     <li>The result of invoking <a>serialize a comma-separated list</a> on performing <a>serialize a
     URL</a> or <a>serialize a LOCAL</a> for each source on the source list.</li>

     <li>The string "<code>;</code>", i.e., SEMICOLON (U+003B).</li>
    </ol>
   </li>

   <li link-type=descriptor>If rule's associated '@font-face/unicode-range' descriptor is present, a single
   SPACE (U+0020), followed by the string "<code>unicode-range:</code>", followed by a single SPACE
   (U+0020), followed by the result of performing serialize a <<'@font-face/unicode-range'>>, followed by the
   string "<code>;</code>", i.e., SEMICOLON (U+003B).</li>

   <li link-type=descriptor>If rule's associated 'font-variant' descriptor is present, a single
   SPACE (U+0020), followed by the string "<code>font-variant:</code>", followed by a single SPACE
   (U+0020), followed by the result of performing serialize a <<'font-variant'>>, followed by the
   string "<code>;</code>", i.e., SEMICOLON (U+003B).</li>

   <li link-type=descriptor>If rule's associated 'font-feature-settings' descriptor is present, a
   single SPACE (U+0020), followed by the string "<code>font-feature-settings:</code>", followed by
   a single SPACE (U+0020), followed by the result of performing serialize a
   <<'font-feature-settings'>>, followed by the string "<code>;</code>", i.e., SEMICOLON
   (U+003B).</li>

   <li link-type=descriptor>If rule's associated 'font-stretch' descriptor is present, a single
   SPACE (U+0020), followed by the string "<code>font-stretch:</code>", followed by a single SPACE
   (U+0020), followed by the result of performing serialize a <<'font-stretch'>>, followed by the
   string "<code>;</code>", i.e., SEMICOLON (U+003B).</li>

   <li link-type=descriptor>If rule's associated 'font-weight' descriptor is present, a single SPACE
   (U+0020), followed by the string "<code>font-weight:</code>", followed by a single SPACE
   (U+0020), followed by the result of performing serialize a <<'font-weight'>>, followed by the
   string "<code>;</code>", i.e., SEMICOLON (U+003B).</li>

   <li link-type=descriptor>If rule's associated 'font-style' descriptor is present, a single SPACE
   (U+0020), followed by the string "<code>font-style:</code>", followed by a single SPACE (U+0020),
   followed by the result of performing serialize a <<'font-style'>>, followed by the string
   "<code>;</code>", i.e., SEMICOLON (U+003B).</li>

   <li>A single SPACE (U+0020), followed by the string "}", i.e., RIGHT CURLY BRACKET (U+007D).</li>
  </ol>

  Issue: Need to define how the {{CSSFontFaceRule}} descriptors' values are serialized.

 <dt>{{CSSPageRule}}
 <dd>

  Issue: Need to define how {{CSSPageRule}} is serialized.

 <dt>{{CSSNamespaceRule}}
 <dd>The literal string "<code>@namespace</code>", followed by a single SPACE
 (U+0020), followed by the
 <a lt="serialize an identifier">serialization as an identifier</a> of the
 {{CSSNamespaceRule/prefix}} attribute (if
 any), followed by a single SPACE (U+0020) if there is a prefix, followed by the
 <a lt="serialize a URL">serialization as URL</a> of the
 {{CSSNamespaceRule/namespaceURI}}
 attribute, followed the character "<code>;</code>" (U+003B).

 <dt>{{CSSKeyframesRule}}
 <dd>
  The result of concatenating the following:
  <ol>
   <li>The literal string "<code>@keyframes</code>", followed by a single SPACE (U+0020).
   <li>The serialization of the {{CSSKeyframesRule/name}} attribute. If the attribute is a CSS wide keyword, or the value <css>default</css>, or the value <css>none</css>,
    then it is [=serialized as a string=]. Otherwise, it is <a lt="serialize an identifier">serialized as an identifier</a>.
   <li>The string "<code> { </code>", i.e., a single SPACE (U+0020), followed by LEFT CURLY BRACKET (U+007B), followed by a single SPACE (U+0020).
   <li>The result of performing <a>serialize a CSS rule</a> on each rule in the rule's {{CSSKeyframesRule/cssRules}} list, separated by a newline and indented by two spaces.</li>
   <li>A newline, followed by the string "}", i.e., RIGHT CURLY BRACKET (U+007D)</li>
  </ol>

 <dt>{{CSSKeyframeRule}}
 <dd>
  The result of concatenating the following:
  <ol>
   <li>The {{CSSKeyframeRule/keyText}}.
   <li>The string "<code> { </code>", i.e., a single SPACE (U+0020), followed by LEFT CURLY BRACKET (U+007B), followed by a single SPACE (U+0020).
   <li>The result of performing <a>serialize a CSS declaration block</a> on the rule's associated declarations.
   <li>If the rule is associated with one or more declarations, the string "<code> </code>", i.e., a single SPACE (U+0020).
   <li>The string "<code>}</code>", RIGHT CURLY BRACKET (U+007D).
  </ol>
</dl>

Issue: The "indented by two spaces" bit matches browsers, but needs work, see <a href="https://github.com/w3c/csswg-drafts/issues/5494">#5494</a>

To <dfn export>insert a CSS rule</dfn> <var>rule</var> in a CSS rule list <var>list</var> at index <var>index</var>,
with a flag <var>nested</var>,
follow these steps:
<ol>
 <li>Set <var>length</var> to the number of items in <var>list</var>.
 <li>If <var>index</var> is greater than <var>length</var>, then <a>throw</a>
 an {{IndexSizeError}} exception.
 <li>Set <var>new rule</var> to the results of performing <a>parse a CSS rule</a>
 on argument <var>rule</var>.
 <li>If <var>new rule</var> is a syntax error, and <var>nested</var> is set,
 perform the following substeps:
  <ul>
   <li> Set <var>declarations</var> to the results of performing <a>parse a CSS declaration block</a>,
   on argument <var>rule</var>.
   <li> If <var>declarations</var> is empty, <a>throw</a> a {{SyntaxError}} exception.
   <li> Otherwise, set <var>new rule</var> to a new [=nested declarations rule=]
   with <var>declarations</var> as it contents.
  </ul>
 <li>If <var>new rule</var> is a syntax error, <a>throw</a>
 a {{SyntaxError}} exception.
 <li>If <var>new rule</var> cannot be inserted into <var>list</var> at the zero-indexed position <var>index</var> due to constraints
 specified by CSS, then <a>throw</a>
 a {{HierarchyRequestError}} exception. [[!CSS21]]

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

 <li>If <var>new rule</var> is an <code>@namespace</code> at-rule, and <var>list</var> contains anything other than
 <code>@import</code> at-rules, and <code>@namespace</code> at-rules,
 <a>throw</a> an {{InvalidStateError}} exception.
 <li>Insert <var>new rule</var> into <var>list</var> at the zero-indexed position <var>index</var>.
 <li>Return <var>index</var>.
</ol>

<wpt>
  serialize-media-rule.html
</wpt>

To <dfn export>remove a CSS rule</dfn> from a CSS rule list <var>list</var> at index <var>index</var>, follow these steps:
<ol>
 <li>Set <var>length</var> to the number of items in <var>list</var>.
 <li>If <var>index</var> is greater than or equal to <var>length</var>, then <a>throw</a>
 an {{IndexSizeError}} exception.
 <li>Set <var>old rule</var> to the <var>index</var>th item in <var>list</var>.
 <li>If <var>old rule</var> is an <code>@namespace</code> at-rule, and <var>list</var> contains anything other than
 <code>@import</code> at-rules, and <code>@namespace</code> at-rules,
 <a>throw</a> an {{InvalidStateError}} exception.
 <li>Remove rule <var>old rule</var> from <var>list</var> at the zero-indexed position <var>index</var>.
 <li>Set <var>old rule</var>'s <a for=CSSRule>parent CSS rule</a> and
 <a for=CSSRule>parent CSS style sheet</a> to null.
</ol>


### The {{CSSRuleList}} Interface ### {#the-cssrulelist-interface}

The {{CSSRuleList}} interface represents an ordered collection of [=CSS rules=].

<pre class=idl>
[Exposed=Window]
interface CSSRuleList {
  getter CSSRule? item(unsigned long index);
  readonly attribute unsigned long length;
};
</pre>

<wpt>
  CSSRuleList.html
</wpt>

The object's <a>supported property indices</a> 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
<a>supported property indices</a>.

The <dfn method for=CSSRuleList>item(<var>index</var>)</dfn> method must return the <var>index</var>th {{CSSRule}}
object in the collection. If there is no <var>index</var>th object in the collection, then the method must return null.

The <dfn attribute for=CSSRuleList>length</dfn> attribute must return the number of {{CSSRule}} objects represented by the
collection.

### The {{CSSRule}} Interface ### {#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.

<pre class=idl>
[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;
};
</pre>

The <dfn attribute for=CSSRule>cssText</dfn> attribute must return a <a lt="serialize a CSS rule">serialization</a> of the
<a for=/>CSS rule</a>.
On setting the {{CSSRule/cssText}} attribute must do nothing.

<wpt>
  css-style-reparse.html
  cssom-cssText-serialize.html
  cssom-ruleTypeAndOrder.html
  declaration-block-all-crash.html
</wpt>

The <dfn attribute for=CSSRule>parentRule</dfn> attribute must return the <a for=CSSRule>parent CSS
rule</a>.

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

The <dfn attribute for=CSSRule>parentStyleSheet</dfn> attribute must return the
<a for=CSSRule>parent CSS style sheet</a>.

Note: The only circumstance where null is returned when a rule has been <a lt="remove a CSS rule">removed</a>.

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

The <dfn attribute for=CSSRule>type</dfn> attribute is deprecated.
It must return an integer, as follows:

<dl class=switch dfn-type=const dfn-for=CSSRule>
 <dt>If the object is a {{CSSStyleRule}}
 <dd>Return 1.
 <dt>If the object is a {{CSSImportRule}}
 <dd>Return 3.
 <dt>If the object is a {{CSSMediaRule}}
 <dd>Return 4.
 <dt>If the object is a {{CSSFontFaceRule}}
 <dd>Return 5.
 <dt>If the object is a {{CSSPageRule}}
 <dd>Return 6.
 <dt>If the object is a {{CSSKeyframesRule}}
 <dd>Return 7.
 <dt>If the object is a {{CSSKeyframeRule}}
 <dd>Return 8.
 <dt>If the object is a {{CSSMarginRule}}
 <dd>Return 9.
 <dt>If the object is a {{CSSNamespaceRule}}
 <dd>Return 10.
 <dt>If the object is a {{CSSCounterStyleRule}}
 <dd>Return 11.
 <dt>If the object is a {{CSSSupportsRule}}
 <dd>Return 12.
 <dt>If the object is a {{CSSFontFeatureValuesRule}}
 <dd>Return 14.
 <dt>Otherwise
 <dd>Return 0.
</dl>

Note: The practice of using an integer enumeration
and several constants to <em>identify</em> 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 <code highlight=js>rule.constructor.name</code>,
which will return a string like <code highlight=js>"CSSStyleRule"</code>.
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.

<wpt hidden title="Tested in other specs">
  <!-- Part of CSSOM View 1 -->
  caretPositionFromPoint.html
  caretPositionFromPoint-audioVideo.html
  caretPositionFromPoint-with-transformation.html

  <!-- Part of CSS Conditional 3 -->
  CSSConditionRule-conditionText.html

  <!-- Part of CSS Counter Styles 3 -->
  CSSCounterStyleRule.html

  <!-- Part of CSS Fonts 3 -->
  CSSFontFaceRule.html
  CSSFontFeatureValuesRule.html
  cssom-fontfacerule-constructors.html
  cssom-fontfacerule.html

  <!-- Part of CSS Animations 1 -->
  CSSKeyframeRule.html
  CSSKeyframesRule.html

  <!-- Part of CSS Custom Properties 1 -->
  serialize-variable-reference.html
  variable-names.html
</wpt>

### The {{CSSStyleRule}} Interface ### {#the-cssstylerule-interface}

The <code>CSSStyleRule</code> interface represents a style rule.

<pre class=idl>
[Exposed=Window]
interface CSSStyleRule : CSSGroupingRule {
  attribute CSSOMString selectorText;
  [SameObject, PutForwards=cssText] readonly attribute CSSStyleProperties style;
};
</pre>

The <dfn attribute for=CSSStyleRule>selectorText</dfn> attribute, on getting, must return the result of
<a lt="serialize a group of selectors">serializing</a> the rule's associated [=selector list=].
On setting the {{CSSStyleRule/selectorText}} attribute these steps must be run:
<ol>
 <li>Run the <a>parse a group of selectors</a> algorithm on the given value.
 <li>If the algorithm returns a non-null value replace the associated [=selector list=] with the returned value.
 <li>Otherwise, if the algorithm returns a null value, do nothing.
</ol>

<wpt>
  CSSStyleRule.html
  CSSStyleRule-set-selectorText.html
  CSSStyleRule-set-selectorText-namespace.html
  selectorText-modification-restyle-001.html
  selectorText-modification-restyle-002.html
  set-selector-text-attachment.html
</wpt>

The <dfn attribute for=CSSStyleRule>style</dfn> attribute must return a {{CSSStyleProperties}} object for the style rule, with the
following properties:
<dl>
 <dt><a for="CSSStyleDeclaration">computed flag</a>
 <dd>Unset.
 <dt><a for="CSSStyleDeclaration">readonly flag</a>
 <dd>Unset.
 <dt><a for="CSSStyleDeclaration">declarations</a>
 <dd>The declared declarations in the rule, in <a>specified order</a>.
 <dt><a for="CSSStyleDeclaration">parent CSS rule</a>
 <dd>[=this=].
 <dt><a for="CSSStyleDeclaration">owner node</a>
 <dd>Null.
</dl>

The <dfn id=concept-declarations-specified-order>specified order</dfn> 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]]


### The {{CSSImportRule}} Interface ### {#the-cssimportrule-interface}

The <code>CSSImportRule</code> interface represents an <code>@import</code> at-rule.

<pre class=idl>
[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;
};
</pre>

The <dfn attribute for=CSSImportRule>href</dfn> attribute must return the <a for="/">URL</a> specified by
the <code>@import</code> at-rule.

Note: To get the resolved <a for="/">URL</a> use the {{StyleSheet/href}}
attribute of the associated <a>CSS style sheet</a>.

The <dfn attribute for=CSSImportRule>media</dfn> attribute must return the value of the {{StyleSheet/media}}
attribute of the associated <a>CSS style sheet</a>.

The <dfn attribute for=CSSImportRule>styleSheet</dfn> attribute must return the associated <a>CSS style sheet</a>, if any, or null otherwise.

The <dfn attribute for=CSSImportRule>layerName</dfn> attribute must return the <l spec=css-cascade-5>[=layer name=]</l> 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 <dfn attribute for=CSSImportRule>supportsText</dfn> 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 <code>@import</code> at-rule might not have an associated <a>CSS style sheet</a> (e.g., if it has a non-matching <code>supports()</code> condition).

<wpt>
  cssimportrule.html
  cssimportrule-parent.html
  cssimportrule-sheet-identity.html
</wpt>

### The {{CSSGroupingRule}} Interface ### {#the-cssgroupingrule-interface}

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

<pre class=idl>
[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);
};
</pre>

The <dfn attribute for=CSSGroupingRule>cssRules</dfn> attribute must return a <code>CSSRuleList</code> object for the
<a for=CSSRule>child CSS rules</a>.

The <dfn method for=CSSGroupingRule>insertRule(<var>rule</var>, <var>index</var>)</dfn> method must return the result of
invoking <a>insert a CSS rule</a> <var>rule</var> into the <a for=CSSRule>child CSS rules</a> at
<var>index</var>, with the <var>nested</var> flag set.

The <dfn method for=CSSGroupingRule>deleteRule(<var>index</var>)</dfn> method must <a>remove a CSS rule</a> from the
<a for=CSSRule>child CSS rules</a> at <var>index</var>.

<wpt>
  CSSGroupingRule-cssRules.html
  CSSGroupingRule-insertRule.html
</wpt>

### The {{CSSMediaRule}} Interface ### {#the-cssmediarule-interface}

The {{CSSMediaRule}} interface is defined in <cite>CSS Conditional Rules</cite>.
[[!CSS3-CONDITIONAL]]


### The {{CSSPageRule}} Interface ### {#the-csspagerule-interface}

The <code>CSSPageRule</code> interface represents an <code>@page</code> at-rule.

Issue: Need to define the rules for
<dfn export>parse a list of CSS page selectors</dfn> and
<dfn export>serialize a list of CSS page selectors</dfn>.

<pre class=idl>
[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 style;
};
</pre>

The <dfn attribute for=CSSPageRule>selectorText</dfn> attribute, on getting, must return the result of
<a lt="serialize a list of CSS page selectors">serializing</a> the associated [=selector list=].
On setting the {{CSSPageRule/selectorText}} attribute  these steps must be run:
<ol>
 <li>Run the <a>parse a list of CSS page selectors</a> algorithm on the given value.
 <li>If the algorithm returns a non-null value replace the associated [=selector list=] with the returned value.
 <li>Otherwise, if the algorithm returns a null value, do nothing.
</ol>

The <dfn attribute for=CSSPageRule>style</dfn> attribute must return a <code>CSSPageDescriptors</code> object for the
<code>@page</code> at-rule, with the following properties:
<dl>
 <dt><a for="CSSStyleDeclaration">computed flag</a>
 <dd>Unset.
 <dt><a for="CSSStyleDeclaration">readonly flag</a>
 <dd>Unset.
 <dt><a for="CSSStyleDeclaration">declarations</a>
 <dd>The declared descriptors in the rule, in <a>specified order</a>.
 <dt><a for="CSSStyleDeclaration">parent CSS rule</a>
 <dd>[=this=].
 <dt><a for="CSSStyleDeclaration">owner node</a>
 <dd>Null.
</dl>

<wpt>
  cssom-pagerule.html
</wpt>

### The {{CSSMarginRule}} Interface ### {#the-cssmarginrule-interface}

The <code>CSSMarginRule</code> interface represents a margin at-rule (e.g. <code>@top-left</code>) in an <code>@page</code> at-rule.
[[!CSS3PAGE]]

<pre class=idl>
[Exposed=Window]
interface CSSMarginRule : CSSRule {
  readonly attribute CSSOMString name;
  [SameObject, PutForwards=cssText] readonly attribute CSSMarginDescriptors style;
};
</pre>

The <dfn attribute for=CSSMarginRule>name</dfn> attribute must return the name of the margin at-rule. The <code>@</code> character is not
included in the name. [[!CSS3SYN]]

The <dfn attribute for=CSSMarginRule>style</dfn> attribute must return a <code>CSSMarginDescriptors</code> object for the
margin at-rule, with the following properties:
<dl>
 <dt><a for="CSSStyleDeclaration">computed flag</a>
 <dd>Unset.
 <dt><a for="CSSStyleDeclaration">readonly flag</a>
 <dd>Unset.
 <dt><a for="CSSStyleDeclaration">declarations</a>
 <dd>The declared declarations in the rule, in <a>specified order</a>.
 <dt><a for="CSSStyleDeclaration">parent CSS rule</a>
 <dd>[=this=].
 <dt><a for="CSSStyleDeclaration">owner node</a>
 <dd>Null.
</dl>


### The {{CSSNamespaceRule}} Interface ### {#the-cssnamespacerule-interface}

The <code>CSSNamespaceRule</code> interface represents an <code>@namespace</code> at-rule.

<pre class=idl>
[Exposed=Window]
interface CSSNamespaceRule : CSSRule {
  readonly attribute CSSOMString namespaceURI;
  readonly attribute CSSOMString prefix;
};
</pre>

The <dfn attribute for=CSSNamespaceRule>namespaceURI</dfn> attribute must return the namespace of the
<code>@namespace</code> at-rule.

The <dfn attribute for=CSSNamespaceRule>prefix</dfn> attribute must return the prefix of the <code>@namespace</code> at-rule or the
empty string if there is no prefix.

<wpt>
  at-namespace.html
  CSSNamespaceRule.html
</wpt>

CSS Declarations {#css-declarations}
------------------------------------

A <dfn export>CSS declaration</dfn> is an abstract concept that is not exposed as an object in the DOM. A <a>CSS declaration</a> has the following associated
properties:

<dl export>
 <dt><dfn for="CSS declaration">property name</dfn>
 <dd>The property name of the declaration.
 <dt><dfn for="CSS declaration">value</dfn>
 <dd>The value of the declaration represented as a list of component values.
 <dt><dfn for="CSS declaration">important flag</dfn>
 <dd>Either set or unset. Can be changed.
 <dt><dfn for="CSS declaration">case-sensitive flag</dfn>
 <dd>Set if the <a for="CSS declaration">property name</a> is defined to be case-sensitive according to its specification,
 otherwise unset.
</dl>

CSS Declaration Blocks {#css-declaration-blocks}
------------------------------------------------

A <dfn export>CSS declaration block</dfn> is an ordered collection of CSS
properties with their associated values, also named <a>CSS declarations</a>. In
the DOM a <a>CSS declaration block</a> is a
<code>CSSStyleDeclaration</code> object. A
<a>CSS declaration block</a> has the following associated properties:

<dl dfn-for="CSSStyleDeclaration" export>
 <dt><dfn>computed flag</dfn>
 <dd>Set if the object is a computed style declaration, rather than a specified
     style. Unless otherwise stated it is unset.

 <dt><dfn>readonly flag</dfn>
 <dd>Set if the object is not modifiable.</dd>

 <dt><dfn>declarations</dfn>
 <dd>The <a>CSS declarations</a> associated with the object.

 <dt><dfn>parent CSS rule</dfn>
 <dd>The <a for=/>CSS rule</a> that the <a>CSS declaration block</a> is associated with, if any, or null otherwise.

 <dt><dfn>owner node</dfn>
 <dd>The {{Element}} that the <a>CSS declaration block</a> is associated with, if any, or
 null otherwise.

 <dt><dfn>updating flag</dfn>
 <dd>Unset by default. Set when the <a>CSS declaration block</a> is updating
 the <a for="CSSStyleDeclaration">owner node</a>'s <code>style</code> attribute.
</dl>

To <dfn export>parse a CSS declaration block</dfn> from a string <var>string</var>, follow these steps:

<ol>
 <li>Let <var>declarations</var> be the returned declarations from invoking <a>parse a block's contents</a> with <var>string</var>.
 <li>Let <var>parsed declarations</var> be a new empty list.
 <li>For each item <var>declaration</var> in <var>declarations</var>, follow these substeps:
  <ol>
   <li>Let <var>parsed declaration</var> be the result of parsing <var>declaration</var> according to the appropriate CSS specifications, dropping parts that
   are said to be ignored. If the whole declaration is dropped, let <var>parsed declaration</var> be null.
   <li>If <var>parsed declaration</var> is not null, append it to <var>parsed declarations</var>.
  </ol>
 <li>Return <var>parsed declarations</var>.
</ol>

To <dfn export>serialize a CSS declaration</dfn> with property name <var>property</var>, value <var>value</var> and optionally an <i>important</i> flag set, follow
these steps:

<ol>
 <li>Let <var>s</var> be the empty string.
 <li>Append <var>property</var> to <var>s</var>.
 <li>Append "<code>: </code>" (U+003A U+0020) to <var>s</var>.
 <li>If <var>value</var> contains any non-whitespace characters,
    append <var>value</var> to <var>s</var>.
 <li>If the <i>important</i> flag is set, append "<code> !important</code>" (U+0020 U+0021 U+0069 U+006D U+0070 U+006F U+0072 U+0074 U+0061 U+006E
 U+0074) to <var>s</var>.
 <li>Append "<code>;</code>" (U+003B) to <var>s</var>.
 <li>Return <var>s</var>.
</ol>

<wpt>
  serialization-CSSDeclaration-with-important.html
</wpt>

To <dfn export>serialize a CSS declaration block</dfn> <var>declaration block</var> means to run the steps below:

<ol>
 <li>Let <var>list</var> be an empty array.
 <li>Let <var>already serialized</var> be an empty array.
 <li><i>Declaration loop</i>: For each <a>CSS declaration</a> <var>declaration</var> in <var>declaration block</var>'s
 <a for="CSSStyleDeclaration">declarations</a>, follow these substeps:
  <ol>
   <li>Let <var>property</var> be <var>declaration</var>'s <a for="CSS declaration">property name</a>.
   <li>If <var>property</var> is in <var>already serialized</var>, continue with the steps labeled <i>declaration loop</i>.
   <li>If <var>property</var> maps to one or more shorthand properties, let <var>shorthands</var> be an array of those shorthand properties, in
   <a>preferred order</a>.
   <li><i>Shorthand loop</i>: For each <var>shorthand</var> in <var>shorthands</var>, follow these substeps:
    <ol>
     <li>Let <var>longhands</var> be an array consisting of all <a>CSS declarations</a> in <var>declaration block</var>'s
     <a for="CSSStyleDeclaration">declarations</a> that are not in <var>already serialized</var> and have a
     <a for="CSS declaration">property name</a> that
     maps to one of the shorthand properties in <var>shorthands</var>.
     <li>If not all properties that map to <var>shorthand</var> are present in <var>longhands</var>, continue with the steps labeled <i>shorthand loop</i>.
     <li>Let <var>current longhands</var> be an empty array.
     <li>Append all <a>CSS declarations</a> in <var>longhands</var> that have a
     <a for="CSS declaration">property name</a> that maps to <var>shorthand</var> to <var>current longhands</var>.
     <li>If there are one or more <a>CSS declarations</a> in <var>current longhands</var> that have their
     <a for="CSS declaration">important flag</a> set and one or more with it unset, continue with
     the steps labeled <i>shorthand loop</i>.
     <li>If there is any declaration in <var>declaration block</var> in between the first and the last longhand in <var>current longhands</var>
     which belongs to the same [=logical property group=], but has a different [=mapping logic=] as any of the longhands in <var>current longhands</var>,
     and is not in <var>current longhands</var>, continue with the steps labeled <i>shorthand loop</i>.
     <li>Let <var>value</var> be the result of invoking <a>serialize a CSS value</a> with <var>current longhands</var>.
     <li>If <var>value</var> is the empty string, continue with the steps labeled <i>shorthand loop</i>.
     <li>Let <var>serialized declaration</var> be the result of invoking <a>serialize a CSS declaration</a> with property name
     <var>shorthand</var>, value <var>value</var>, and the <i>important</i> flag set if the <a>CSS declarations</a> in
     <var>current longhands</var> have their <a for="CSS declaration">important flag</a> set.
     <li>Append <var>serialized declaration</var> to <var>list</var>.
     <li>Append the property names of all items of <var>current longhands</var> to <var>already serialized</var>.
     <li>Continue with the steps labeled <i>declaration loop</i>.
    </ol>
   <li>Let <var>value</var> be the result of invoking <a>serialize a CSS value</a> of <var>declaration</var>.
   <li>Let <var>serialized declaration</var> be the result of invoking <a>serialize a CSS declaration</a> with property name <var>property</var>, value
   <var>value</var>, and the <i>important</i> flag set if <var>declaration</var> has its <a for="CSS declaration">important
   flag</a> set.
   <li>Append <var>serialized declaration</var> to <var>list</var>.
   <li>Append <var>property</var> to <var>already serialized</var>.
  </ol>
 <li>Return <var>list</var> joined with "<code> </code>" (U+0020).
</ol>

Note: The serialization of an empty CSS declaration block is the empty string.

Note: The serialization of a non-empty CSS declaration block does not include any surrounding whitespace, i.e., no whitespace appears
before the first property name and no whitespace appears after the final semicolon delimiter that follows the last property value.

<wpt>
  border-shorthand-serialization.html
  css-style-attr-decl-block.html
  font-family-serialization-001.html
  font-shorthand-serialization.html
  font-variant-shorthand-serialization.html
  shorthand-serialization.html
  shorthand-values.html
</wpt>

A <a>CSS declaration block</a> has these <a>attribute change steps</a> for its <a for="CSSStyleDeclaration">owner node</a>
with <var>localName</var>, <var>value</var>, and <var>namespace</var>:

<ol>
 <li>If the <a for="CSSStyleDeclaration">computed flag</a> is set, then return.
 <li>If the <a for="CSSStyleDeclaration">updating flag</a> is set, then return.
 <li>If <var>localName</var> is not "<code>style</code>", or <var>namespace</var> is not null, then return.
 <li>If <var>value</var> is null, empty the <a for="CSSStyleDeclaration">declarations</a>.
 <li>Otherwise, let the <a for="CSSStyleDeclaration">declarations</a> be the result of <a>parse a CSS declaration block</a>
 from a string <var>value</var>.
</ol>

When a <a>CSS declaration block</a> object is created, then:

<ol>
 <li>Let <var>owner node</var> be the <a for="CSSStyleDeclaration">owner node</a>.
 <li>If <var>owner node</var> is null, or the <a for="CSSStyleDeclaration">computed flag</a> is set, then return.
 <li>Let <var>value</var> be the result of <a lt="get an attribute by namespace and local name">getting an attribute</a>
 given null, "<code>style</code>", and <var>owner node</var>.
 <li>If <var>value</var> is not null, let the <a for="CSSStyleDeclaration">declarations</a> be the result of
 <a>parse a CSS declaration block</a> from a string <var>value</var>.
</ol>

To <dfn export>update style attribute for</dfn> <var>declaration block</var> means to run the steps below:

<ol>
 <li>Assert: <var>declaration block</var>'s <a for="CSSStyleDeclaration">computed flag</a> is unset.
 <li>Let <var>owner node</var> be <var>declaration block</var>'s <a for="CSSStyleDeclaration">owner node</a>.
 <li>If <var>owner node</var> is null, then return.
 <li>Set <var>declaration block</var>'s <a for="CSSStyleDeclaration">updating flag</a>.
 <li><a>Set an attribute value</a> for <var>owner node</var> using "<code>style</code>" and the result of
 <a lt="serialize a CSS declaration block">serializing</a> <var>declaration block</var>.
 <li>Unset <var>declaration block</var>'s <a for="CSSStyleDeclaration">updating flag</a>.
</ol>

The <dfn export id=concept-shorthands-preferred-order>preferred order</dfn> of a list of shorthand properties <var>shorthands</var> is as follows:

<ol>
 <li>Order <var>shorthands</var> lexicographically.
 <li>Move all items in <var>shorthands</var> that begin with "<code>-</code>" (U+002D) last in the list, retaining their relative order.
 <li>Move all items in <var>shorthands</var> that begin with "<code>-</code>" (U+002D) but do not begin with "<code>-webkit-</code>" last in the
 list, retaining their relative order.
 <li>Order <var>shorthands</var> by the number of longhand properties that map to it, with the greatest number first.
</ol>

### The {{CSSStyleDeclaration}} Interface ### {#the-cssstyledeclaration-interface}

The <code>CSSStyleDeclaration</code> interface represents a <a>CSS declaration block</a>, including its underlying state, where this
underlying state depends upon the source of the <code>CSSStyleDeclaration</code> instance.

<pre class=idl>
[Exposed=Window]
interface CSSStyleDeclaration {
  [CEReactions] attribute CSSOMString cssText;
  readonly attribute unsigned long length;
  getter CSSOMString item(unsigned long index);
  CSSOMString getPropertyValue(CSSOMString property);
  CSSOMString getPropertyPriority(CSSOMString property);
  [CEReactions] undefined setProperty(CSSOMString property, [LegacyNullToEmptyString] CSSOMString value, optional [LegacyNullToEmptyString] CSSOMString priority = "");
  [CEReactions] CSSOMString removeProperty(CSSOMString property);
  readonly attribute CSSRule? parentRule;
};

[Exposed=Window]
interface CSSStyleProperties : CSSStyleDeclaration {
  [CEReactions] attribute [LegacyNullToEmptyString] CSSOMString cssFloat;
};
</pre>

<wpt>
  css-style-declaration-modifications.html
  cssom-cssstyledeclaration-set.html
  cssstyledeclaration-all-shorthand.html
  cssstyledeclaration-cssfontrule.tentative.html
  cssstyledeclaration-csstext-all-shorthand.html
  cssstyledeclaration-csstext-final-delimiter.html
  cssstyledeclaration-csstext-important.html
  cssstyledeclaration-csstext-setter.window.html
  cssstyledeclaration-csstext.html
  cssstyledeclaration-custom-properties.html
  cssstyledeclaration-mutability.html
  cssstyledeclaration-mutationrecord-001.html
  cssstyledeclaration-mutationrecord-002.html
  cssstyledeclaration-mutationrecord-003.html
  cssstyledeclaration-mutationrecord-004.html
  cssstyledeclaration-mutationrecord-005.html
  cssstyledeclaration-properties.html
  cssstyledeclaration-registered-custom-properties.html
  cssstyledeclaration-removeProperty-all.html
  cssstyledeclaration-setter-attr.html
  cssstyledeclaration-setter-declarations.html
  cssstyledeclaration-setter-form-controls.html
  cssstyledeclaration-setter-logical.html
  page-descriptors.html
  property-accessors.html
</wpt>

The object's <a>supported property indices</a> are the numbers in the range zero to one less than the number of
<a>CSS declarations</a> in the <a for="CSSStyleDeclaration">declarations</a>. If there are no such
<a>CSS declarations</a>, then there are no <a>supported property indices</a>.

Getting the <dfn attribute for="CSSStyleDeclaration">cssText</dfn> attribute must run these steps:

1. If the <a for="CSSStyleDeclaration">computed flag</a> is set, then return the empty string.
2. Return the result of <a lt="serialize a CSS declaration block">serializing</a> the <a for="CSSStyleDeclaration">declarations</a>.

Setting the {{CSSStyleDeclaration/cssText}} attribute must run these steps:
<ol>
 <li>If the <a for="CSSStyleDeclaration">readonly flag</a> is set,
 then <a>throw</a> a {{NoModificationAllowedError}} exception.
 <li>Empty the <a for="CSSStyleDeclaration">declarations</a>.
 <li><a lt="Parse a CSS declaration block">Parse</a> the given value and, if the return value is not the empty list, insert the items in the list
 into the <a for="CSSStyleDeclaration">declarations</a>, in <a>specified order</a>.
 <li><a>Update style attribute for</a> the <a>CSS declaration block</a>.
</ol>

The <dfn attribute for=CSSStyleDeclaration>length</dfn> attribute must return the number of <a lt="CSS declaration">CSS
declarations</a> in the <a for="CSSStyleDeclaration">declarations</a>.

The <dfn method for=CSSStyleDeclaration>item(<var>index</var>)</dfn> method must return the
<a for="CSS declaration">property name</a> of the <a>CSS declaration</a> at position <var>index</var>. If there is no <var>index</var>th object in the collection, then the method must return the empty string.

The <dfn method for=CSSStyleDeclaration>getPropertyValue(<var>property</var>)</dfn> method must run these steps:
<ol>
 <li>If <var>property</var> is not a <a>custom property</a>, follow these substeps:
  <ol>
   <li>Let <var>property</var> be <var>property</var> <a lt="ASCII lowercase">converted to ASCII lowercase</a>.
   <li>If <var>property</var> is a shorthand property, then follow these substeps:
    <ol>
     <li>Let <var>list</var> be a new empty array.
     <li>For each longhand property <var>longhand</var> that <var>property</var> maps to, in canonical order, follow these substeps:
      <ol>
       <li>If <var>longhand</var> is a <a>case-sensitive</a> match for a <a for="CSS declaration">property
       name</a> of a <a>CSS declaration</a> in the <a for="CSSStyleDeclaration">declarations</a>, let <var>declaration</var>
       be that <a>CSS declaration</a>, or null otherwise.
       <li>If <var>declaration</var> is null, then return the empty string.
       <li>Append the <var>declaration</var> to <var>list</var>.
      </ol>
     <li>If <a lt="important flag" for="CSS declaration">important flags</a> of all declarations in <var>list</var> are same,
     then return the <a lt="serialize a CSS value">serialization</a> of <var>list</var>.
     <li>Return the empty string.
    </ol>
  </ol>
 <li>If <var>property</var> is a <a>case-sensitive</a>
 match for a <a for="CSS declaration">property name</a> of a <a>CSS declaration</a> in the
 <a for="CSSStyleDeclaration">declarations</a>, then return the result of invoking
 <a>serialize a CSS value</a> of that declaration.
 <li>Return the empty string.
</ol>

<wpt>
  cssom-getPropertyValue-common-checks.html
  serialize-all-longhands.html
</wpt>

The <dfn method for=CSSStyleDeclaration>getPropertyPriority(<var>property</var>)</dfn> method must run these steps:
<ol>
 <li>If <var>property</var> is not a <a>custom property</a>, follow these substeps:
  <ol>
   <li>Let <var>property</var> be <var>property</var> <a lt="ASCII lowercase">converted to ASCII lowercase</a>.
   <li>If <var>property</var> is a shorthand property, follow these substeps:
    <ol>
     <li>Let <var>list</var> be a new array.
     <li>For each longhand property <var>longhand</var> that <var>property</var> maps to, append the result of invoking
     {{CSSStyleDeclaration/getPropertyPriority()}} with <var>longhand</var> as argument to <var>list</var>.
     <li>If all items in <var>list</var> are the string "<code>important</code>", then return the string "<code>important</code>".
    </ol>
  </ol>
 <li>If <var>property</var> is a
 <a>case-sensitive</a> match for a <a for="CSS declaration">property name</a> of a <a>CSS
 declaration</a> in the <a for="CSSStyleDeclaration">declarations</a> that has the
 <a for="CSS declaration">important flag</a> set, return the string "<code>important</code>".
 <li>Return the empty string.
</ol>
<div class=example>E.g. for <code>background-color:lime !IMPORTANT</code> the return
value would be "<code>important</code>".</div>

The <dfn method for=CSSStyleDeclaration>setProperty(<var>property</var>, <var>value</var>, <var>priority</var>)</dfn> method must run these steps:
<ol>
 <li>If the <a for="CSSStyleDeclaration">readonly flag</a> is set,
 then <a>throw</a> a {{NoModificationAllowedError}} exception.
 <li>If <var>property</var> is not a <a>custom property</a>, follow these substeps:
  <ol>
   <li>Let <var>property</var> be <var>property</var> <a lt="ASCII lowercase">converted to ASCII lowercase</a>.
   <li>If <var>property</var> is not a <a>case-sensitive</a> match for a <a>supported CSS property</a>, then return.
  </ol>
 <li>If <var>value</var> is the empty string, invoke {{CSSStyleDeclaration/removeProperty()}}
 with <var>property</var> as argument and return.
 <li>If <var>priority</var> is not the empty string and is not an <a>ASCII case-insensitive</a> match for the string
 "<code>important</code>", then return.
 <li>
  Let <var>component value list</var> be the result of <a lt="parse a CSS value">parsing</a> <var>value</var> for property <var>property</var>.

  Note: <var>value</var> can not include "<code>!important</code>".

 <li>If <var>component value list</var> is null, then return.
 <li>Let <var>updated</var> be false.
 <li>If <var>property</var> is a shorthand property, then for each longhand property <var>longhand</var> that <var>property</var> maps to, in canonical
 order, follow these substeps:
  <ol>
   <li>Let <var>longhand result</var> be the result of <a lt="set a CSS declaration">set the CSS declaration</a>
   <var>longhand</var> with the appropriate value(s) from <var>component value list</var>, with the <i>important</i>
   flag set if <var>priority</var> is not the empty string, and unset otherwise, and with the list of declarations
   being the <a for="CSSStyleDeclaration">declarations</a>.
   <li>If <var>longhand result</var> is true, let <var>updated</var> be true.
  </ol>
 <li>Otherwise, let <var>updated</var> be the result of <a lt="set a CSS declaration">set the CSS declaration</a>
 <var>property</var> with value <var>component value list</var>, with the <i>important</i> flag set if
 <var>priority</var> is not the empty string, and unset otherwise, and with the list of declarations being the
 <a for="CSSStyleDeclaration">declarations</a>.
 <li>If <var>updated</var> is true, <a>update style attribute for</a> the <a>CSS declaration block</a>.
</ol>

<wpt>
  cssom-setProperty-shorthand.html
  MutationObserver-style.html
  rule-restrictions.html
  setproperty-null-undefined.html
</wpt>

To <dfn export>set a CSS declaration</dfn> <var>property</var> with a value <var>component value list</var> and optionally with an <i>important</i> flag set, in
a list of declarations <var>declarations</var>, the user agent must ensure the following constraints hold after its steps:

<ul>
 <li>
  Exactly one <a>CSS declaration</a> whose <a for="CSS declaration">property name</a> is a
  <a>case-sensitive</a> match of <var>property</var> must exist in <var>declarations</var>.
  Such declaration is referenced as the <var>target declaration</var> below.

 <li>
  The <var>target declaration</var> must have value being <var>component value list</var>,
  and <var>target declaration</var>'s <a for="CSS declaration">important flag</a> must be
  <a>set</a> if <i>important</i> flag is set, and <a>unset</a> otherwise.

 <li>
  Any <a>CSS declaration</a> which is not the <var>target declaration</var> must not be changed, inserted,
  or removed from <var>declarations</var>.

 <li>
  If there are <a>CSS declarations</a> in <var>declarations</var> whose
  <a for="CSS declaration">property name</a> is in the same <a>logical property group</a> as
  <var>property</var>, but has a different <a>mapping logic</a>, <var>target declaration</var> must be
  at an index after all of those <a>CSS declarations</a>.

 <li>
  The steps must return true if the serialization of <var>declarations</var> was changed as result
  of the steps. It may return false otherwise.
</ul>

Issue: Should we add something like "Any observable side effect must not be made outside
<var>declarations</var>"? The current constraints sound like a hole for undefined behavior.

Note: The steps of <a>set a CSS declaration</a> are not defined in this level of CSSOM. User agents may
use different algorithms as long as the constraints above hold.

<div class="example">
 The simplest way to conform with the constraints would be to always remove any existing declaration
 matching <var>property</var>, and append the new declaration to the end. But based on implementation
 feedback, this approach would likely regress performance.

 Another possible algorithm is:
 <ol>
  <li>If <var>property</var> is a <a>case-sensitive</a> match for a <a for="CSS declaration">property name</a>
   of a <a>CSS declaration</a> in <var>declarations</var>, follow these substeps:
   <ol>
    <li>Let <var>target declaration</var> be such <a>CSS declaration</a>.
    <li>Let <var>needs append</var> be false.
    <li><a for="list">For each</a> <var>declaration</var> in <var>declarations</var> after
     <var>target declaration</var>:
     <ol>
      <li>If <var>declaration</var>'s <a for="CSS declaration">property name</a> is not in the same
       <a>logical property group</a> as <var>property</var>, then <a>continue</a>.
      <li>If <var>declaration</var>' <a for="CSS declaration">property name</a> has the same
       <a>mapping logic</a> as <var>property</var>, then <a>continue</a>.
      <li>Let <var>needs append</var> be true.
      <li><a>Break</a>.
     </ol>
     <li>If <var>needs append</var> is false, then:
      <ol>
       <li>Let <var>needs update</var> be false.
       <li>If <var>target declaration</var>'s <a for="CSS declaration">value</a> is not equal to <var>component
        value list</var>, then let <var>needs update</var> be true.
       <li>If <var>target declaration</var>'s <a for="CSS declaration">important flag</a> is not equal to
        whether <i>important</i> flag is set, then let <var>needs update</var> be true.
       <li>If <var>needs update</var> is false, then return false.
       <li>Set <var>target declaration</var>'s <a for="CSS declaration">value</a> to <var>component value list</var>.
       <li>If <i>important</i> flag is set, then set <var>target declaration</var>'s
        <a for="CSS declaration">important flag</a>, otherwise unset it.
       <li>Return true.
      </ol>
     <li>Otherwise, remove <var>target declaration</var> from <var>declarations</var>.
   </ol>
  <li>Append a new <a>CSS declaration</a> with <a for="CSS declaration">property name</a> <var>property</var>,
   <a for="CSS declaration">value</a> <var>component value list</var>, and <a for="CSS declaration">important flag</a>
   set if <i>important</i> flag is set to <var>declarations</var>.
  <li>Return true.
 </ol>
</div>

The <dfn method for=CSSStyleDeclaration>removeProperty(<var>property</var>)</dfn> method must run these steps:
<ol>
 <li>If the <a for="CSSStyleDeclaration">readonly flag</a> is set,
 then <a>throw</a> a {{NoModificationAllowedError}} exception.
 <li>If <var>property</var> is not a <a>custom property</a>,
 let <var>property</var> be <var>property</var> <a lt="ASCII lowercase">converted to ASCII lowercase</a>.
 <li>Let <var>value</var> be the return value of invoking {{CSSStyleDeclaration/getPropertyValue()}}
 with <var>property</var> as argument.
 <li>Let <var>removed</var> be false.
 <li>If <var>property</var> is a shorthand property, for each longhand property <var>longhand</var> that <var>property</var> maps to:
  <ol>
   <li>If <var>longhand</var> is not a <a for="CSS declaration">property name</a> of a <a>CSS declaration</a>
   in the <a for="CSSStyleDeclaration">declarations</a>, <a for=iteration>continue</a>.
   <li>Remove that <a>CSS declaration</a> and let <var>removed</var> be true.
  </ol>
 <li>Otherwise, if <var>property</var> is a <a>case-sensitive</a> match for a
 <a for="CSS declaration">property name</a> of a <a>CSS declaration</a> in the
 <a for="CSSStyleDeclaration">declarations</a>, remove that <a>CSS declaration</a> and let <var>removed</var> be true.
 <li>If <var>removed</var> is true, <a>Update style attribute for</a> the <a>CSS declaration block</a>.
 <li>Return <var>value</var>.
</ol>

The <dfn attribute for=CSSStyleDeclaration>parentRule</dfn> attribute must return the
<a for="CSSStyleDeclaration">parent CSS rule</a>.

The <dfn attribute for=CSSStyleProperties>cssFloat</dfn>
attribute, on getting, must return the result of invoking
{{CSSStyleDeclaration/getPropertyValue()}} with
<code>float</code> as argument. On setting, the attribute must invoke
{{CSSStyleDeclaration/setProperty()}} with
<code>float</code> as first argument, as second argument the given value, and no third argument.
Any exceptions thrown must be re-thrown.

For each CSS property <var>property</var> that is a <a>supported CSS property</a>,
the following partial interface applies where <dfn attribute for=CSSStyleProperties>camel-cased attribute</dfn>
is obtained by running the <a>CSS property to IDL attribute</a> algorithm for
<var>property</var>.

<wpt>
  change-rule-with-layers-crash.html
  style-attr-update-across-documents.html
</wpt>

<pre class="idl extract">
partial interface CSSStyleProperties {
  [CEReactions] attribute [LegacyNullToEmptyString] CSSOMString _<var>camel_cased_attribute</var>;
};
</pre>

The <a attribute for=CSSStyleProperties><var>camel-cased attribute</var></a> attribute, on getting, must return the
result of invoking {{CSSStyleDeclaration/getPropertyValue()}} with the
argument being the result of running the <a>IDL attribute to CSS property</a>
algorithm for <var>camel-cased attribute</var>.

Setting the <a attribute for=CSSStyleProperties><var>camel-cased attribute</var></a> attribute must invoke
{{CSSStyleDeclaration/setProperty()}} with the
first argument being the result of running the <a>IDL attribute to CSS property</a>
algorithm for <var>camel-cased attribute</var>, as second argument the given value, and no third argument. Any
exceptions thrown must be re-thrown.

<div class=example>For example, for the 'font-size' property there would be a <code>fontSize</code> IDL attribute.</div>

For each CSS property <var>property</var> that is a <a>supported CSS property</a> and that begins
with the string <code>-webkit-</code>, the following partial interface applies where
<var>webkit-cased attribute</var> is obtained by running the <a>CSS property to IDL attribute</a>
algorithm for <var>property</var>, with the <i>lowercase first</i> flag set.

<pre class="idl extract">
partial interface CSSStyleProperties {
  [CEReactions] attribute [LegacyNullToEmptyString] CSSOMString _<var>webkit_cased_attribute</var>;
};
</pre>

The <dfn attribute for=CSSStyleProperties><var>webkit-cased attribute</var></dfn> attribute, on
getting, must return the result of invoking {{CSSStyleDeclaration/getPropertyValue()}} with the
argument being the result of running the <a>IDL attribute to CSS property</a> algorithm for
<var>webkit-cased attribute</var>, with the <i>dash prefix</i> flag set.

Setting the <a attribute for=CSSStyleDeclaration><var>webkit-cased attribute</var></a>
attribute must invoke {{CSSStyleDeclaration/setProperty()}} with the first argument being the result
of running the <a>IDL attribute to CSS property</a> algorithm for <var>webkit-cased attribute</var>,
with the <i>dash prefix</i> flag set, as second argument the given value, and no third argument.
Any exceptions thrown must be re-thrown.

<div class=example>For example, if the user agent supports the '-webkit-transform' property, there
would be a <code>webkitTransform</code> IDL attribute. There would also be a
<code>WebkitTransform</code> IDL attribute because of the rules for camel-cased attributes.</div>

For each CSS property <var>property</var> that is a <a>supported CSS property</a>,
except for properties that have no "<code>-</code>" (U+002D) in the property name,
the following partial interface applies where <var>dashed attribute</var> is <var>property</var>.

<pre class="idl extract">
partial interface CSSStyleProperties {
  [CEReactions] attribute [LegacyNullToEmptyString] CSSOMString _<var>dashed_attribute</var>;
};
</pre>

The <dfn attribute for=CSSStyleProperties><var>dashed attribute</var></dfn> attribute, on getting, must return the
result of invoking {{CSSStyleDeclaration/getPropertyValue()}} with the
argument being <var>dashed attribute</var>.

Setting the <a attribute for=CSSStyleProperties><var>dashed attribute</var></a> attribute must invoke
{{CSSStyleDeclaration/setProperty()}} with the
first argument being <var>dashed attribute</var>, as second argument the given value, and no third argument. Any
exceptions thrown must be re-thrown.

<div class=example>
 For example, for the 'font-size' property there would be a <code>font-size</code> IDL attribute. In JavaScript, the property can be accessed as
 follows, assuming <var>element</var> is an <a lt="HTML elements">HTML element</a>:
 <pre><var>element</var>.style['font-size'];</pre>
</div>

The <dfn export>CSS property to IDL attribute</dfn> algorithm for <var>property</var>, optionally with a
<i>lowercase first</i> flag set, is as follows:

<ol>
 <li>Let <var>output</var> be the empty string.

 <li>Let <var>uppercase next</var> be unset.

 <li>If the <i>lowercase first</i> flag is set, remove the first character from <var>property</var>.

 <li>For each character <var>c</var> in <var>property</var>:

  <ol>
   <li>If <var>c</var> is "<code>-</code>" (U+002D), let <var>uppercase next</var> be set.

   <li>Otherwise, if <var>uppercase next</var> is set, let <var>uppercase next</var> be unset and append <var>c</var>
   <a lt="ASCII uppercase">converted to ASCII uppercase</a> to <var>output</var>.

   <li>Otherwise, append <var>c</var> to <var>output</var>.
  </ol>

 <li>Return <var>output</var>.
</ol>

The <dfn export>IDL attribute to CSS property</dfn> algorithm for <var>attribute</var>, optionally with a
<i>dash prefix</i> flag set, is as follows:

<ol>
 <li>Let <var>output</var> be the empty string.

 <li>If the <i>dash prefix</i> flag is set, append "<code>-</code>" (U+002D) to <var>output</var>.

 <li>For each character <var>c</var> in <var>attribute</var>:

  <ol>
   <li>If <var>c</var> is in the range U+0041 to U+005A (ASCII uppercase), append "<code>-</code>" (U+002D) followed by <var>c</var>
   <a lt="ASCII lowercase">converted to ASCII lowercase</a> to <var>output</var>.

   <li>Otherwise, append <var>c</var> to <var>output</var>.
  </ol>

 <li>Return <var>output</var>.
</ol>


CSS Values {#css-values}
------------------------


### Parsing CSS Values ### {#parsing-css-values}

To <dfn export>parse a CSS value</dfn> <var>value</var> for a given
<var>property</var> means to follow these steps:

<ol>
 <li>Let <var>list</var> be the value returned by invoking <a>parse a list of component values</a> from <var>value</var>.
 <li>Match <var>list</var> against the grammar for the property <var>property</var> in the CSS specification.
 <li>If the above step failed, return null.
 <li>Return <var>list</var>.
</ol>

Note: "<code>!important</code>" declarations are not
part of the property value space and will therefore cause
<a>parse a CSS value</a> to return null.


### Serializing CSS Values ### {#serializing-css-values}

<!-- based on http://damowmow.com/playground/canon.txt -->

To <dfn export>serialize a CSS value</dfn> of a <a>CSS declaration</a> |declaration|
or a list of longhand <a lt="CSS declaration">CSS declarations</a> |list|,
follow these rules:

1. If this algorithm is invoked with a [=list=] |list|:
    1. Let |shorthand| be the first shorthand property,
        in [=preferred order=],
        that exactly maps to all of the longhand properties in |list|.
    2. If there is no such shorthand or
         |shorthand| cannot exactly represent the values of all the properties in |list|,
        return the empty string.
    3. Otherwise, [=serialize a CSS value=]
        from a hypothetical declaration of the property |shorthand|
        with its value representing the combined values of the declarations in |list|.
2. Represent the value of the |declaration|
    as a [=list=] of CSS component values |components|
    that, when [=CSS/parsed=] according to the property's grammar,
    would represent that value.
    Additionally, unless otherwise specified:

    * If certain component values can appear in any order
        without changing the meaning of the value
        (a pattern typically represented by a double bar <a grammar>||</a> in the value syntax),
        reorder the component values to use the canonical order of component values
        as given in the property definition table.
    * If component values can be omitted or replaced with a shorter representation
        without changing the meaning of the value,
        omit/replace them.
    * If either of the above syntactic translations would be less backwards-compatible,
        do not perform them.

    Note: The rules described here outline the <em>general principles</em> of serialization.
    For legacy reasons, some properties serialize in a different manner,
    which is intentionally undefined here due to lack of resources.
    Please consult that property's specification and/or your local reverse-engineer for details.
3. Remove any <<whitespace-token>>s from |components|.
3. Replace each component value in |components|
    with the result of invoking [=serialize a CSS component value=].
4. Join the items of |components| into a single string,
    inserting " " (U+0020 SPACE) between each pair of items
    unless the second item is a "," (U+002C COMMA)
    Return the result.

<wpt>
  flex-serialization.html
  overflow-serialization.html
  serialize-values.html
</wpt>

To
<dfn export>serialize a CSS component value</dfn>
depends on the component, as follows:

<dl class="switch">
 <dt>[=keyword=]
 <dd>The keyword
 <a lt="ASCII lowercase">converted to ASCII lowercase</a>.

 <dt><<angle>>
 <dd>
  The &lt;number> component serialized as per &lt;number> followed by the unit in canonical form as defined in its respective specification.

  Issue: Probably should distinguish between declared and computed / resolved values.

 <dt><<color>>
 <dd>
 If &lt;color&gt; is a component of a resolved value, see [[css-color-4#resolving-color-values]].

 If &lt;color&gt; is a component of a computed value, see [[css-color-4#serializing-color-values]].


 If <<color>> is a component of a declared value, then
for sRGB values, see
[[css-color-4#resolving-sRGB-values]].
For other color functions, see
[[css-color-4#resolving-color-values]].

 <dt><<alpha-value>>
 <dd>
 See [[css-color-4#serializing-alpha-values]].

 <dt><<counter>>
 <dd>
  The return value of the following algorithm:
  <ol>
   <li>Let <var>s</var> be the empty string.
   <li>If &lt;counter> has three CSS component values append the string
   "<code>counters(</code>" to <var>s</var>.
   <li>If &lt;counter> has two CSS component values append the string
   "<code>counter(</code>" to <var>s</var>.
   <li>Let <var>list</var> be a list of CSS component values belonging to &lt;counter>, omitting the last CSS component value if it is "decimal".
   <li>Let each item in <var>list</var> be the result of invoking <a>serialize a CSS component value</a> on that item.
   <li>Append the result of invoking <a>serialize a comma-separated list</a> on <var>list</var> to <var>s</var>.
   <li>Append "<code>)</code>" (U+0029) to <var>s</var>.
   <li>Return <var>s</var>.
  </ol>


 <dt><<frequency>>
 <dd>
  The &lt;number> component serialized as per &lt;number> followed by the unit in its canonical form as defined in its respective specification.

  Issue: Probably should distinguish between declared and computed / resolved values.

 <dt><<identifier>>
 <dd>The identifier
 <a lt="serialize an identifier">serialized as an identifier</a>.

 <dt><<integer>>
 <dd>A base-ten integer using digits 0-9 (U+0030 to U+0039) in the
 shortest form possible, preceded by "<code>-</code>" (U+002D) if it is
 negative.

 <dt><<length>>
 <dd>
  The &lt;number> component serialized as per &lt;number> followed by the unit in its canonical form as defined in its respective specification.

  Issue: Probably should distinguish between declared and computed / resolved values.

 <dt><<number>>
 <dd>
  A base-ten number using digits 0-9 (U+0030 to U+0039) in the shortest form possible,
  using "<code>.</code>" to separate decimals (if any),
  rounding the value if necessary to not produce more than 6 decimals,
  preceded by "<code>-</code>" (U+002D) if it is negative.

  Note: scientific notation is not used.

 <dt><<percentage>>
 <dd>The &lt;number> component serialized as per &lt;number> followed
 by the literal string "<code>%</code>" (U+0025).

 <dt><<resolution>>
 <dd>The resolution in dots per <a lt=px value>CSS pixel</a> serialized as per
 &lt;number> followed by the literal string "<code>dppx</code>".

 <dt><<ratio>>
 <dd>The numerator serialized as per &lt;number>
     followed by the literal string "<code> / </code>",
     followed by the denominator serialized as per &lt;number>.

 <dt><<shape>>
 <dd>
  The return value of the following algorithm:
  <ol>
   <li>Let <var>s</var> be the string "<code>rect(</code>".
   <li>Let <var>list</var> be a list of the CSS component values belonging to &lt;shape>.
   <li>Let each item in <var>list</var> be the result of invoking <a>serialize a CSS component value</a> of that item.
   <li>Append the result of invoking <a>serialize a comma-separated list</a> on <var>list</var> to <var>s</var>.
   <li>Append "<code>)</code>" (U+0029) to <var>s</var>.
   <li>Return <var>s</var>.
  </ol>


 <dt><<string>>
 <dt><<font-family-name>>
 <dd>The string
 <a lt="serialize a string">serialized as a string</a>.

 <dt><<time>>
 <dd>The time in seconds serialized as per &lt;number> followed by
 the literal string "<code>s</code>".

 <dt><<url>>
 <dd>The <a>absolute-URL string</a>
 <a lt="serialize a URL">serialized as URL</a>.

 Issue: This should differentiate declared and computed <<url>> values, see <a href="https://github.com/w3c/csswg-drafts/issues/3195">#3195</a>.
</dl>


 &lt;absolute-size>,
 &lt;border-width>,
 &lt;border-style>,
 &lt;bottom>,
 &lt;generic-font-family>,
 &lt;generic-voice>,
 &lt;left>,
 &lt;margin-width>,
 &lt;padding-width>,
 &lt;relative-size>,
 &lt;right>, and
 &lt;top>,
 are considered macros by this specification. They all represent instances
 of components outlined above.

Issue: One idea is that we can remove this section somewhere in
the CSS3/CSS4 timeline by moving the above definitions to the drafts that
define the CSS components.

<wpt>
  serialize-custom-props.html
</wpt>

#### Examples #### {#serializing-css-values-examples}

Here are some examples of before and after results on declared values.
The before column could be what the author wrote in a style sheet, while
the after column shows what querying the DOM would return.

<div class="example">
 <table class="complex data">
  <thead>
   <tr><th>Before<th>After
  <tbody>
   <tr><td><code>background: none</code><td><code>background: rgba(0, 0, 0, 0)</code>
   <tr><td><code>outline: none</code><td><code>outline: invert</code>
   <tr><td><code>border: none</code><td><code>border: medium</code>
   <tr><td><code>list-style: none</code><td><code>list-style: disc</code>
   <tr><td><code>margin: 0 1px 1px 1px</code><td><code>margin: 0px 1px 1px</code>
   <tr><td><code>azimuth: behind left</code><td><code>azimuth: 220deg</code>
   <tr><td><code>font-family: a, 'b"', serif</code><td><code>font-family: "a", "b\"", serif</code>
   <tr><td><code>content: url('h)i') '\[\]'</code><td><code>content: url("h)i") "[]"</code>
   <tr><td><code>azimuth: leftwards</code><td><code>azimuth: leftwards</code>
   <tr><td><code>color: rgb(18, 52, 86)</code><td><code>color: #123456</code>
   <tr><td><code>color: rgba(000001, 0, 0, 1)</code><td><code>color: #000000</code>
 </table>

 Issue: Some of these need to be updated per the new rules.
</div>


DOM Access to CSS Declaration Blocks {#dom-access-to-css-declaration-blocks}
============================================================================


<h3 id="the-elementcssinlinestyle-mixin" oldids="the-elementcssinlinestyle-interface">
The {{ElementCSSInlineStyle}} Mixin</h3>

The <code>ElementCSSInlineStyle</code> mixin provides access to inline style properties of an element.

<pre class=idl>
interface mixin ElementCSSInlineStyle {
  [SameObject, PutForwards=cssText] readonly attribute CSSStyleProperties style;
};
</pre>

The <dfn attribute for=ElementCSSInlineStyle>style</dfn> attribute must return a {{CSSStyleProperties}} object whose
<a for="CSSStyleDeclaration">readonly flag</a> is unset, whose <a for="CSSStyleDeclaration">parent CSS rule</a> is null, and
whose <a for="CSSStyleDeclaration">owner node</a> is [=this=].

If the user agent supports HTML, the following IDL applies: [[HTML]]

<pre class=idl>
HTMLElement includes ElementCSSInlineStyle;
</pre>

If the user agent supports SVG, the following IDL applies: [[SVG11]]

<pre class=idl>
SVGElement includes ElementCSSInlineStyle;
</pre>

If the user agent supports MathML, the following IDL applies: [[MathML-Core]]

<pre class=idl>
MathMLElement includes ElementCSSInlineStyle;
</pre>

<wpt>
  css-style-attribute-modifications.html
  inline-style-001.html
</wpt>

Extensions to the {{Window}} Interface {#extensions-to-the-window-interface}
----------------------------------------------------------------------------

<pre class=idl>
partial interface Window {
  [NewObject] CSSStyleProperties getComputedStyle(Element elt, optional CSSOMString? pseudoElt);
};
</pre>

The <dfn method for=Window>getComputedStyle(<var>elt</var>, <var>pseudoElt</var>)</dfn> method must run these
steps:
<ol>
 <li>Let <var>doc</var> be <var>elt</var>'s <a>node document</a>.
 <li>Let <var>obj</var> be <var>elt</var>.
 <li>If <var>pseudoElt</var> is provided, is not the empty string, and starts with a colon, then:
  <ol>
    <li>[=CSS/Parse=] <var>pseudoElt</var> as a <<pseudo-element-selector>>, and let <var>type</var> be the result.
    <li>If <var>type</var> is failure, or is a ''::slotted()'' or ''::part()'' pseudo-element, let <var>obj</var> be null.
    <li>Otherwise let <var>obj</var> be the given pseudo-element of <var>elt</var>.
  </ol>

  Note: CSS2 pseudo-elements should match both the double and single-colon
  versions. That is, both <code>:before</code> and <code>::before</code> should
  match above.

 <li>Let <var>decls</var> be an empty list of <a>CSS declarations</a>.
 <li>If <var>obj</var> is not null, and <var>elt</var> is <a>connected</a>,
  part of the <a>flat tree</a>,
  and its <a>shadow-including root</a> has a <a>browsing context</a> which either
  doesn't have a <a>browsing context container</a>, or whose
  <a>browsing context container</a> is <a>being rendered</a>,
  set <var>decls</var> to a list of all longhand properties that are
  <a lt="supported CSS property">supported CSS properties</a>, in lexicographical order,
  with the value being the <a>resolved value</a> computed for <var>obj</var>
  using the style rules associated with <var>doc</var>. Additionally, append to
  <var>decls</var> all the <a>custom properties</a> whose <a>computed value</a>
  for <var>obj</var> is not the <a>guaranteed-invalid value</a>.

  Issue: There are UAs that handle shorthands, and all UAs handle shorthands
  that used to be longhands like 'overflow', see
  <a href="https://github.com/w3c/csswg-drafts/issues/2529">#2529</a>.

  Issue: Order of custom properties is currently undefined, see
  <a href="https://github.com/w3c/csswg-drafts/issues/4947">#4947</a>.

 <li>
  Return a live {{CSSStyleProperties}} object with the following properties:
  <dl>
   <dt><a for="CSSStyleDeclaration">computed flag</a>
   <dd>Set.
   <dt><a for="CSSStyleDeclaration">readonly flag</a>
   <dd>Set.
   <dt><a for="CSSStyleDeclaration">declarations</a>
   <dd><var>decls</var>.
   <dt><a for="CSSStyleDeclaration">parent CSS rule</a>
   <dd>Null.
   <dt><a for="CSSStyleDeclaration">owner node</a>
   <dd><var>obj</var>.
  </dl>
</ol>

<p class=warning>The {{Window/getComputedStyle()}} method exposes information from <a lt="CSS style sheet">CSS style
sheets</a> with the <a>origin-clean flag</a> unset.

<wpt>
getComputedStyle-animations-replaced-into-ib-split.html
getComputedStyle-detached-subtree.html
getComputedStyle-display-none-001.html
getComputedStyle-display-none-002.html
getComputedStyle-display-none-003.html
getComputedStyle-dynamic-subdoc.html
getComputedStyle-getter-v-properties.tentative.html
getComputedStyle-insets-absolute-crash.html
getComputedStyle-insets-absolute-logical-crash.html
getComputedStyle-insets-absolute-roundtrip.html
getComputedStyle-insets-absolute.html
getComputedStyle-insets-fixed.html
getComputedStyle-insets-grid.html
getComputedStyle-insets-multicol-absolute-crash.html
getComputedStyle-insets-nobox.html
getComputedStyle-insets-relative.html
getComputedStyle-insets-relpos-inline.html
getComputedStyle-insets-static.html
getComputedStyle-insets-sticky-container-for-abspos.html
getComputedStyle-insets-sticky.html
getComputedStyle-layout-dependent-removed-ib-sibling.html
getComputedStyle-layout-dependent-replaced-into-ib-split.html
getComputedStyle-line-height.html
getComputedStyle-logical-enumeration.html
getComputedStyle-margins-roundtrip.html
getComputedStyle-property-order.html
getComputedStyle-pseudo-checkmark.html
getComputedStyle-pseudo-picker-icon.html
getComputedStyle-pseudo-with-argument.html
getComputedStyle-pseudo.html
getComputedStyle-resolved-colors.html
getComputedStyle-resolved-min-max-clamping.html
getComputedStyle-resolved-min-size-auto.html
getComputedStyle-special-chars-crash.html
getComputedStyle-sticky-pos-percent.html
getComputedStyle-width-scroll.tentative.html
</wpt>

Utility APIs {#utility-apis}
============================

The <code>CSS.escape()</code> Method {#the-css.escape()-method}
------------------------------------------------------

The <code>CSS</code> namespace holds useful CSS-related functions that do not belong elsewhere.

<pre class=idl>
[Exposed=Window]
namespace CSS {
  CSSOMString escape(CSSOMString ident);
};
</pre>

<wpt>
  CSS-namespace-object-class-string.html
</wpt>

Issue: This was previously specified as an IDL interface
that only held static methods.
Switching to an IDL namespace is *nearly* identical,
so it's expected that there won't be any compat concerns.
If any are discovered, please report
so we can consider reverting this change.

The <dfn method for=CSS>escape(<var>ident</var>)</dfn> operation must return the result of invoking <a>serialize an identifier</a> of
<var>ident</var>.

<div class=example>
 For example, to serialize a string for use as part of a selector, the {{CSS/escape()}} method can be used:
 <pre>var element = document.querySelector('#' + CSS.escape(id) + ' > img');</pre>
</div>

<div class=example>
 The {{CSS/escape()}} method can also be used for escaping strings, although it escapes characters that don't strictly need to be
 escaped:
 <pre>var element = document.querySelector('a[href="#' + CSS.escape(fragment) + '"]');</pre>
</div>

Specifications that define operations on the {{CSS}} namespace and want to
store some state should store the state on the <a spec=html>current global
object</a>'s <a spec=html>associated <code>Document</code></a>.
<!-- https://github.com/w3c/csswg-drafts/issues/180 -->

<wpt>
  escape.html
</wpt>

Resolved Values {#resolved-values}
==================================

{{Window/getComputedStyle()}} was
historically defined to return the "computed value" of an element or
pseudo-element. However, the concept of "computed value" changed between
revisions of CSS while the implementation of
{{Window/getComputedStyle()}} had to
remain the same for compatibility with deployed scripts. To address this
issue this specification introduces the concept of a
<dfn export>resolved value</dfn>.

The <a>resolved value</a> for a given longhand property can be determined
as follows:

<dl class="switch">
 <dt>'background-color'
 <dt>'border-block-end-color'
 <dt>'border-block-start-color'
 <dt>'border-bottom-color'
 <dt>'border-inline-end-color'
 <dt>'border-inline-start-color'
 <dt>'border-left-color'
 <dt>'border-right-color'
 <dt>'border-top-color'
 <dt>'box-shadow'
 <dt>'caret-color'
 <dt>'color'
 <dt>'outline-color'
 <dt>A <dfn export>resolved value special case property like 'color'</dfn> defined in another specification
 <dd>The <a>resolved value</a> is the <a>used value</a>.

 <dt>'line-height'
 <dd>The <a>resolved value</a> is ''line-height/normal'' if the <a>computed value</a> is ''line-height/normal'', or the <a>used value</a> otherwise.

 <dt>'block-size'
 <dt>'height'
 <dt>'inline-size'
 <dt>'margin-block-end'
 <dt>'margin-block-start'
 <dt>'margin-bottom'
 <dt>'margin-inline-end'
 <dt>'margin-inline-start'
 <dt>'margin-left'
 <dt>'margin-right'
 <dt>'margin-top'
 <dt>'padding-block-end'
 <dt>'padding-block-start'
 <dt>'padding-bottom'
 <dt>'padding-inline-end'
 <dt>'padding-inline-start'
 <dt>'padding-left'
 <dt>'padding-right'
 <dt>'padding-top'
 <dt>'width'
 <dt>A <dfn export>resolved value special case property like 'height'</dfn> defined in another specification
 <dd>If the property applies to the element or pseudo-element and the <a>resolved value</a> of the
 'display' property is not ''display/none'' or ''display/contents'', then the <a>resolved value</a>
 is the <a>used value</a>. Otherwise the <a>resolved value</a> is the <a>computed value</a>.

 <dt>'bottom'
 <dt>'left'
 <dt>'inset-block-end'
 <dt>'inset-block-start'
 <dt>'inset-inline-end'
 <dt>'inset-inline-start'
 <dt>'right'
 <dt>'top'
 <dt>A <dfn export>resolved value special case property like 'top'</dfn> defined in another specification
 <dd>If the property applies to a positioned element and the <a>resolved value</a> of the 'display'
 property is not ''display/none'' or ''display/contents'', and the property is not over-constrained,
 then the <a>resolved value</a> is the <a>used value</a>. Otherwise the <a>resolved value</a> is the
 <a>computed value</a>.

 <dt>A <dfn export>resolved value special case property</dfn> defined in another specification
 <dd>As defined in the relevant specification.

 <dt>Any other property
 <dd>The <a>resolved value</a> is the <a>computed value</a>.
</dl>

<wpt>
  computed-style-001.html
  computed-style-002.html
  computed-style-003.html
  computed-style-004.html
  computed-style-005.html
  resolved-border-width.html
</wpt>

IANA Considerations {#iana-considerations}
==========================================


Default-Style {#default-style}
------------------------------------------------------------------------------------

This section describes a header field for registration in the Permanent
Message Header Field Registry.
<!--<a href="issue">\[RFC3864]</a>-->

<dl>
 <dt>Header field name
 <dd><dfn lt="http-default-style">Default-Style</dfn>
 <dt>Applicable protocol
 <dd>http
 <dt>Status
 <dd>standard
 <dt>Author/Change controller
 <dd>W3C
 <dt>Specification document(s)
 <dd>This document is the relevant specification.
 <dt>Related information
 <dd>None.
</dl>



Change History {#change-history}
================================

This section documents some of the changes between publications of this specification. This section is not exhaustive. Bug fixes and editorial changes are
generally not listed.

Changes From 17 March 2016 {#changes-from-17-march-2016}
------------------------------------------------------------
* Serialization of <<resolution>> is changed.
* <code>[CEReactions]</code> IDL extended attributes are added.
* Resolved value for logical properties are added.
* <code>getComputedStyle</code> for 'display': ''display/contents'' is changed.
* <code>MediaList.item</code> now returns serialization.
* <code>MediaList.item</code> does not serialize shorthand if importance differs.
* Other specifications are allowed to specify resolved value.
* <code>index</code> argument in <code>insertRule</code> is now optional.
* <code>href</code> attribute of <code>Stylesheet</code> and <code>CSSImportRule</code> now uses <code>USVString</code>.
* <code>CSSOMString</code> is introduced.
* Serialization of <code>CSSMediaRule</code> and <code>CSSFontFaceRule</code> is added.
* <a for="CSSStyleDeclaration">Updating flag</a> is added to CSS declaration block to avoid serialize-and-reparse on style attribute.
* Serialization of a declaration value is now properly defined.
* <code>getComputedStyle</code> now returns the style rules of the node's document.
* A {{TypeError}} is thrown when the pseudo-element passed to <code>getComputedStyle</code> is unknown or ''::slotted()''.
* {{CSS}} is switched from interface to namespace.
* <code>setPropertyValue</code> and <code>setPropertyPriority</code> are removed from {{CSSStyleDeclaration}} due to lack of interest from implementations.
* The <code>styleSheets</code> IDL attribute is moved from {{Document}} to {{DocumentOrShadowRoot}}.
* LinkStyle.sheet now returns <code>CSSStyleSheet</code> instead of <code>StyleSheet</code>
* Deprecated CSSStyleSheet members are defined.
* The <code>CSSRule.type</code> attribute is deprecated.
* Serialization of <<ratio>> is added.
* <code>CSSStyleDeclaration.cssText</code> now returns the empty string for computed style.
* <a>Custom properties</a> are included in <code>getComputedStyle</code>.
* MathML IDL is introduced.
* Serialization of {{CSSKeyframesRule}} and {{CSSKeyframeRule}} is added.
* Serialization of media query is changed.
* A shorthand is not serialized if there are longhands with other property group / mapping logic in between the longhands of that shorthand.
* {{CSSStyleRule}} serialization is aware of nesting now.
* Constructable stylesheets is introduced.

Changes From 5 December 2013 {#changes-from-5-december-2013}
------------------------------------------------------------
* API for alternative stylesheets is removed: <code>selectedStyleSheetSet</code>,
    <code>lastStyleSheetSet</code>, <code>preferredStyleSheetSet</code>,
    <code>styleSheetSets</code>, <code>enableStyleSheetsForSet()</code> on {{Document}}.
* The <code>pseudo()</code> method on {{Element}} and the <code>PseudoElement</code> interface is
    removed.
* The <code>cascadedStyle</code>, <code>defaultStyle</code>, <code>rawComputedStyle</code> and
    <code>usedStyle</code> IDL attributes on {{Element}} are removed.
* The {{CSSRule/cssText}} IDL attribute's setter on {{CSSRule}} is changed to do nothing.
* IDL attributes of the form <code>webkitFoo</code> (with lowercase <code>w</code>) on
    {{CSSStyleDeclaration}} are added.
* {{CSSNamespaceRule}} is changed back to readonly.
* Handling of <code>@charset</code> in {{CSSStyleSheet/insertRule()}} is removed.
* <code>CSSCharsetRule</code> is removed again.
* Serialization of identifiers and strings is changed.
* Serialization of selectors now supports combinators ">>" and "||" and the "i" flag in attribute selectors.
* Serialization of :lang() is changed.
* Serialization of <<color>> and <<number>> is changed.
* {{CSSStyleDeclaration/setProperty()}} on {{CSSStyleDeclaration}} is changed.


Changes From 12 July 2011 To 5 December 2013 {#changes-from-12-july-2011-to-5-december-2013}
--------------------------------------------------------------------------------------------

<ul>
 <li>Cross-origin stylesheets are not allowed to be read or changed.

 <li><code>CSSCharsetRule</code> is re-introduced.

 <li><code>CSSGroupingRule</code> and <code>CSSMarginRule</code> are introduced.

 <li><code>CSSNamespaceRule</code> is now mutable.

 <li><a lt="parse a CSS declaration block">Parse</a> and <a lt="serialize a CSS declaration block">serialize</a> a CSS declaration block is
 now defined.

 <li>Shorthands are now supported in {{CSSStyleDeclaration/setProperty()}},
 {{CSSStyleDeclaration/getPropertyValue()}}, et al.

 <li><code>setPropertyValue</code> and <code>setPropertyPriority</code> are added to {{CSSStyleDeclaration}}.

 <li>The <code>style</code> and <code>media</code> attributes of various interfaces are annotated with the <code>[PutForwards]</code> WebIDL
 extended attribute.

 <li>The <code>pseudo()</code> method on <code>Element</code> is introduced.

 <li>The <code>PseudoElement</code> interface is introduced.

 <li>The <code>cascadedStyle</code>, <code>rawComputedStyle</code> and
 <code>usedStyle</code> attributes on <code>Element</code> and <code>PseudoElement</code> are introduced.

 <li>The <a method for=CSS lt=escape()>CSS.escape()</a> static method is introduced.
</ul>

Security Considerations {#sec}
=======================

No new security considerations have been reported on this specification.

Privacy Considerations {#priv}
======================

No new privacy considerations have been reported on this specification.


Acknowledgments {#acknowledgments}
==================================

The editors would like to thank
Alexey Feldgendler,
Benjamin Poulain,
Bj&ouml;rn H&ouml;hrmann,
Boris Zbasky,
Brian Kardell,
Chris Dumez,
Christian Krebs,
Daniel Glazman,
David Baron,
Domenic Denicola,
Dominique Hazael-Massieux,
<i>fantasai</i>,
Hallvord R. M. Steen,
Ian Hickson,
John Daggett,
Lachlan Hunt,
Mike Sherov,
Myles C. Maxfield,
Morten Stenshorne,
Ms2ger,
Nazım Can Altınova,
Øyvind Stenhaug,
Peter Sloetjes,
Philip Jägenstedt,
Philip Taylor,
Richard Gibson,
Robert O'Callahan,
Simon Sapin,
Sjoerd Visscher,
Sylvain Galineau,
Tarquin Wilton-Jones,
Xidorn Quan, and
Zack Weinberg
for contributing to this specification.

Additional thanks to Ian Hickson for writing the
initial version of the alternative style sheets API and canonicalization
(now serialization) rules for CSS values.

<wpt hidden title="Deprecated tests">
  computed-style-set-property.html
</wpt>

<wpt ignore>
  cssstyledeclaration-csstext-setter.window.js

  <!-- Mutation Events are obsolete -->
  stylesheet-dom-mutation-event-crash.html
</wpt>
