CARVIEW |
CSS Cascading and Inheritance Level 6
W3C First Public Working Draft,
More details about this document
- This version:
- https://www.w3.org/TR/2021/WD-css-cascade-6-20211221/
- Latest published version:
- https://www.w3.org/TR/css-cascade-6/
- Editor's Draft:
- https://drafts.csswg.org/css-cascade-6/
- History:
- https://www.w3.org/standards/history/css-cascade-6
- Feedback:
- CSSWG Issues Repository
- Inline In Spec
- Editors:
- Elika J. Etemad / fantasai (Invited Expert)
- Miriam E. Suzanne (Invited Expert)
- Tab Atkins Jr. (Google)
- Miriam E. Suzanne (Invited Expert)
- Suggest an Edit for this Spec:
- GitHub Editor
Copyright © 2021 W3C® (MIT, ERCIM, Keio, Beihang). W3C liability, trademark and permissive document license rules apply.
Abstract
This CSS module describes how to collate style rules and assign values to all properties on all elements. By way of cascading and inheritance, values are propagated for all properties on all elements.
New in this level is § 2.5 Scoped Styles.
CSS is a language for describing the rendering of structured documents (such as HTML and XML) on screen, on paper, etc.Status of this document
This section describes the status of this document at the time of its publication. A list of current W3C publications and the latest revision of this technical report can be found in the W3C technical reports index at https://www.w3.org/TR/.
This document was published by the CSS Working Group as a First Public Working Draft using the Recommendation track. Publication as a First Public Working Draft does not imply endorsement by W3C and its Members.
This is a draft document and may be updated, replaced or obsoleted by other documents at any time. It is inappropriate to cite this document as other than work in progress.
Please send feedback by filing issues in GitHub (preferred), including the spec code “css-cascade” in the title, like this: “[css-cascade] …summary of comment…”. All issues and comments are archived. Alternately, feedback can be sent to the (archived) public mailing list www-style@w3.org.
This document is governed by the 2 November 2021 W3C Process Document.
This document was produced by a group operating under the W3C Patent Policy. W3C maintains a public list of any patent disclosures made in connection with the deliverables of the group; that page also includes instructions for disclosing a patent. An individual who has actual knowledge of a patent which the individual believes contains Essential Claim(s) must disclose the information in accordance with section 6 of the W3C Patent Policy.
1. Introduction and Missing Sections
This is a diff spec over CSS Cascading and Inheritance Level 5. It is currently an Exploratory Working Draft: if you are implementing anything, please use Level 5 as a reference. We will merge the Level 5 text into this draft once it reaches CR.
2. Cascading
The cascade takes an unordered list of declared values for a given property on a given element, sorts them by their declaration’s precedence as determined below, and outputs a single cascaded value.
2.1. Cascade Sorting Order
The cascade sorts declarations according to the following criteria, in descending order of priority:
- Origin and Importance
-
The origin of a declaration is based on where it comes from
and its importance is
whether or not it is declared with !important (see below).
The precedence of the various origins is, in descending order:
- Transition declarations [css-transitions-1]
- Important user agent declarations
- Important user declarations
- Important author declarations
- Animation declarations [css-animations-1]
- Normal author declarations
- Normal user declarations
- Normal user agent declarations
Declarations from origins earlier in this list win over declarations from later origins.
- Context
-
A document language can provide for blending declarations sourced
from different encapsulation contexts,
such as the nested tree contexts of shadow trees in the [DOM].
When comparing two declarations that are sourced from different encapsulation contexts, then for normal rules the declaration from the outer context wins, and for important rules the declaration from the inner context wins. For this purpose, [DOM] tree contexts are considered to be nested in shadow-including tree order.
Note: This effectively means that normal declarations belonging to an encapsulation context can set defaults that are easily overridden by the outer context, while important declarations belonging to an encapsulation context can enforce requirements that cannot be overridden by the outer context.
- The Style Attribute
- Separately for normal and important declarations, declarations that are attached directly to an element (such as the contents of a style attribute) rather than indirectly mapped by means of a style rule selector take precedence over declarations the same importance that are mapped via style rule.
- Layers
-
Declarations within each origin and context can be explicitly assigned to a cascade layer.
For the purpose of this step,
any declaration not assigned to an explicit layer is added to an implicit final layer.
Cascade layers (like declarations) are ordered by order of appearance. When comparing declarations that belong to different layers, then for normal rules the declaration whose cascade layer is last wins, and for important rules the declaration whose cascade layer is first wins.
Note: This follows the same logic used for layering normal and important origins, so that the !important flag maintains the same “override” purpose in both settings.
- Strong Scoping Proximity
-
If two declarations both have elements
selected by scoped descendant relationships
applying strong scoping proximity,
then the declaration with the fewest generational hops
between the ancestor/descendant element pair wins.
If multiple such pairs are represented, their strong scoping proximity weights are compared from innermost scoping relationship to outermost scoping relationship (with any missing pairs weighted as infinity).
- Specificity
- The Selectors module [SELECT] describes how to compute the specificity of a selector. Each declaration has the same specificity as the style rule it appears in. The declaration with the highest specificity wins.
- Weak Scoping Proximity
-
If two declarations both have elements
selected by scoped descendant relationships
applying weak scoping proximity,
then the declaration with the fewest generational hops
between the ancestor/descendant element pair wins.
If multiple such pairs are represented, their weak scoping proximity weights are compared from innermost scoping relationship to outermost scoping relationship (with any missing pairs weighted as infinity).
- Order of Appearance
-
The last declaration in document order wins.
For this purpose:
- Style sheets are ordered as in final CSS style sheets.
- Declarations from imported style sheets are ordered as if their style sheets were substituted in place of the @import rule.
- Declarations from style sheets independently linked by the originating document are treated as if they were concatenated in linking order, as determined by the host document language.
- Declarations from style attributes are ordered according to the document order of the element the style attribute appears on, and are all placed after any style sheets.
Does scope proximity belong above or below specificity in the cascade? [Issue #6790]
The output of the cascade is a (potentially empty) sorted list of declared values for each property on each element.
2.2. Cascading Origins
CSS Cascading 5 § 6.2 Cascading Origins
cascade origin
2.3. Important Declarations: the !important annotation
CSS Cascading 5 § 6.3 Important Declarations: the !important annotation
important normal
2.4. Cascade Layers
CSS Cascading 5 § 6.4 Cascade Layers
2.5. Scoped Styles
A scope is a subtree or fragment of a document, which can be used by selectors for more targeted matching. Scopes are described in CSS through a combination of two selector lists:
-
The <scope-start> is a <forgiving-selector-list>. Each element matched by <scope-start> is a scoping element, creating a scope with itself as the scoping root.
-
The <scope-end> is a <forgiving-selector-list> that is scoped by the <scope-start> selector, with the scoping roots as :scope elements. Each element matched by <scope-end> is a scoping limit. The scoping limit elements define the lower bounds of a scope, so that scoped selectors are not able to match any elements nested within them.
Each resulting scope includes a scoping root and all its descendants, up to and including any scoping limit elements, but not the descendants of those limits.
Inclusive vs exclusive scope boundaries [Issue #6577]
Note: In contrast to Shadow Encapsulation, which describes a persistent one-to-one relationship in the DOM between a shadow host and its nested shadow tree, multiple overlapping scopes can be defined in relation to the same elements.
@scope ( .light-scheme) { a{ color : darkmagenta; } } @scope ( .dark-scheme) { a{ color : plum; } } @scope ( .media-object) { .media-image{ border-radius : 50 % ; } .media-content{ padding : 1 em ; } }
@scope ( .media-object) to( .content) { img{ border-radius : 50 % ; } /* it is also possible to style the lower limit element itself */ .content{ padding : 1 em ; } }
The img selector will only match image tags that are in a DOM fragment starting with any .media-object, and including all descendants until any intervening .content class.
Should scoping limits be added to the definition of scoped selectors?
/* .content is only a limit when it is a direct child of the :scope */ @scope ( .media-object) to( :scope > .content) { ...}
Scoping limits can also reference elements outside their scoping root by using :scope. For example:
/* .content is only a limit when the :scope is inside .sidebar */ @scope ( .media-object) to( .sidebar :scope .content) { ...}
2.5.1. Scoping Styles: the @scope rule
The @scope block at-rule allows authors to scope style rules in CSS, with the application of weak scoping proximity between the scoping root and the subject of each style rule.
Should @scope use strong or weak scoping proximity? Strong scoping proximity causes declarations to be weighted more strongly by scope proximity than by their selector’s specificity. Weak scoping proximity causes declarations of the same specificity to be weighted by proximity to their scoping root before falling back to source ordering, but declarations of higher specificity win over more tightly-scoped declarations. The Working Group currently leans towards weak proximity, and recommends that as a starting point for prototypes. [Issue #6790]
The syntax of the @scope rule is:
@scope (<scope-start>) [to (<scope-end>)]? { <stylesheet> }
The @scope at-rule has three primary effects on the style rules in its <stylesheet>:
-
Selectors are scoped to the given scope, with the :scope element being the scoping root.
-
Selectors are given the added specificity of the most specific complex selector in the <scope-start> argument.
Note: This is designed to match the behavior of the :is() selector.
-
The cascade prioritizes declarations with a more proximate scoping root, regardless of specificity or source order.
@scope ( #hero) { img{ border-radius : 50 % ; } } #hero img{ border-radius : 50 % ; }
But because img
is scoped,
it is weighted more strongly in the cascade.
main-component
and sub-component
)
and every element is marked as part of one or both scopes
using the data-scope
attribute:
< section data-scope = "main-component" > < p data-scope = "main-component" > ...< p > <!-- sub-component root is in both scopes --> < section data-scope = "main-component sub-component" > <!-- children are only in the inner scope --> < p data-scope = "sub-component" > ...< p > </ section > </ section >
Those custom scope attributes are then appended to every single selector in CSS:
p[ data-scope~='main-component' ] { color : red; } p[ data-scope~='sub-component' ] { color : blue; } /* both sections are part of the outer scope */ section[ data-scope~='main-component' ] { background : snow; } /* the inner section is also part of the inner scope */ section[ data-scope~='sub-component' ] { color : ghostwhite; }
Using the @scope rule, authors and tools can replicate similar behavior with the unique attribute or class applied only to the scoping roots:
< section data-scope = "main-component" > < p > ...< p > < section data-scope = "sub-component" > <!-- children are only in the inner scope --> < p > ...< p > </ section > </ section >
Then the class or attribute can be used for establishing both upper and lower boundaries, such that scopes only overlap at those boundaries:
@scope ([ data-scope='main-component' ]) to([ data-scope]) { p{ color : red; } /* both sections are part of the outer scope */ section{ background : snow; } } @scope ([ data-scope='sub-component' ]) to([ data-scope]) { p{ color : blue; } /* the inner section is also part of the inner scope */ section{ color : ghostwhite; } }
@scope rules can be nested. In this case, just as with the nested style rules, the selectors of the inner @scope (including those defining its scope) are scoped by the selectors of the outer one.
2.5.2. Scoped Descendant Combinator
The scoped descendant combinator describes a descendant relationship between two elements.
A selector of the form A >> B represents
an element B
that is an arbitrary descendant
of some ancestor element A
.
This combinator differs from the descendant combinator in that it applies weak scoping proximity to the relationship between A and B. It does not change the :scope element.
Should the scoped descendant combinator use strong or weak scoping proximity? Should it even exist? It’s defined here to work the way many people expected the regular descendant combinator to work...
In this example
the <a>
element’s color will be determined
by the nearest ancestor with either
a light-scheme or dark-scheme class.
(If the descendant selector had been used,
its color would always be plum,
because it is later in the source order.)
.light-scheme >> a { color: darkmagenta; } .dark-scheme >> a { color: plum; }
However if the <a>
element has a light-scheme ancestor and is focused,
its color will be teal even if it has a nearer dark-scheme ancestor,
because there is no equivalent dark-scheme rule.
.light-scheme >> a:focus { color: teal; }
Note: Most simple scoping relationships can be represented with this syntax, rather than the more complex selector scoping notation defined below.
2.5.3. Selector Scoping Notation
The selector scoping notation allows selectors to be scoped to a subtree of the document, and allows the possibility of excluding nested subtrees. It is prepended to the selector or selector list, and its syntax is as follows:
<selector-scope> = ( <scope-start> [/ <scope-end>]? )
If, after parsing, <scope-start> is an empty list, the selector is valid but matches nothing. Otherwise, the selector matches any element that is within the scope described by the given <scope-start> and <scope-end> selectors.
( .post / .comments) .title{ font-size : 2 em ; }
Without any such lower limits, the selector scoping notation is similar to existing descendant selectors, except that the scoping root can be matched by the selector as well.
The specificity of the most specific complex selector in <scope-start> is added to the specificity of each such scoped selector. The specificity of the <scope-end> is ignored. The selector scoping notation also applies weak scoping proximity between the scoping root and the subject of the scoped selector.
Should this have the same scope proximity weighting as @scope or different scope proximity weighting (or no scope proximity weighting)?
( .ancestor) .child{ color : darkmagenta; } .child:is ( .ancestor, .ancestor *) { color : darkmagenta; } .ancestor.child, .ancestor .child{ color : darkmagenta; }
However the first rule will win, because it also applies weak scoping proximity.
How does this interact with [CSS-NESTING-1]?
This notation was added in order to allow scoping limits
to be applied within querySelector()
.
Is this something we want to have?
2.6. Precedence of Non-CSS Presentational Hints
CSS Cascading 5 § 6.4 Cascade Layers
3. Changes
3.1. Additions Since Level 5
The following features have been added since Level 5:
-
The definition of a scope, as described by a combination of <scope-start> and <scope-end> selectors.
-
The in-scope (:in()) pseudo-class for selecting with lower-boundaries
-
The @scope rule for creating scoped stylesheets
-
The definition of scope proximity in the cascade
3.2. Additions Since Level 4
The following features have been added since Level 4:
-
Added cascade layers to the cascade sort criteria (and defined style attributes as a distinct step of the cascade sort criteria so that they interact appropriately).
-
Introduced the @layer rule for defining cascade layers.
-
Added layer/layer() option to @import definition.
-
Introduced the revert-layer keyword for rolling back values to previous layers.
3.3. Additions Since Level 3
The following features have been added since Level 3:
-
Introduced revert keyword, for rolling back the cascade.
-
Introduced supports() syntax for supports-conditional @import rules.
-
Added encapsulation context to the cascade sort criteria to accommodate Shadow DOM. [DOM]
-
Defined the property two aliasing mechanisms CSS uses to support legacy syntaxes. See CSS Cascading 4 § 3.1 Property Aliasing.
3.4. Additions Since Level 2
The following features have been added since Level 2:
- The all shorthand
- The initial keyword
- The unset keyword
- Incorporation of animations and transitions into the cascade.
Acknowledgments
David Baron, Tantek Çelik, Florian Rivoal, Simon Sapin, Jen Simmons, Giuseppe Gurgone, Keith Grant, Lea Verou, Nicole Sullivan, Theresa O’Connor, and Boris Zbarsky contributed to this specification.
Privacy and Security Considerations
-
The cascade process does not distinguish between same-origin and cross-origin stylesheets, enabling the content of cross-origin stylesheets to be inferred from the computed styles they apply to a document.
-
User preferences and UA defaults expressed via application of style rules are exposed by the cascade process, and can be inferred from the computed styles they apply to a document.
-
The @import rule does not apply the CORS protocol to loading cross-origin stylesheets, instead allowing them to be freely imported and applied.
-
The @import rule assumes that resources without
Content-Type
metadata (or any same-origin file if the host document is in quirks mode) aretext/css
, potentially allowing arbitrary files to be imported into the page and interpreted as CSS, potentially allowing sensitive data to be inferred from the computed styles they apply to a document.
Conformance
Document conventions
Conformance requirements are expressed with a combination of descriptive assertions and RFC 2119 terminology. The key words “MUST”, “MUST NOT”, “REQUIRED”, “SHALL”, “SHALL NOT”, “SHOULD”, “SHOULD NOT”, “RECOMMENDED”, “MAY”, and “OPTIONAL” in the normative parts of this document are to be interpreted as described in RFC 2119. However, for readability, these words do not appear in all uppercase letters in this specification.
All of the text of this specification is normative except sections explicitly marked as non-normative, examples, and notes. [RFC2119]
Examples in this specification are introduced with the words “for example”
or are set apart from the normative text with class="example"
,
like this:
Informative notes begin with the word “Note” and are set apart from the
normative text with class="note"
, like this:
Note, this is an informative note.
Advisements are normative sections styled to evoke special attention and are
set apart from other normative text with <strong class="advisement">
, like
this: UAs MUST provide an accessible alternative.
Conformance classes
Conformance to this specification is defined for three conformance classes:
- style sheet
- A CSS style sheet.
- renderer
- A UA that interprets the semantics of a style sheet and renders documents that use them.
- authoring tool
- A UA that writes a style sheet.
A style sheet is conformant to this specification if all of its statements that use syntax defined in this module are valid according to the generic CSS grammar and the individual grammars of each feature defined in this module.
A renderer is conformant to this specification if, in addition to interpreting the style sheet as defined by the appropriate specifications, it supports all the features defined by this specification by parsing them correctly and rendering the document accordingly. However, the inability of a UA to correctly render a document due to limitations of the device does not make the UA non-conformant. (For example, a UA is not required to render color on a monochrome monitor.)
An authoring tool is conformant to this specification if it writes style sheets that are syntactically correct according to the generic CSS grammar and the individual grammars of each feature in this module, and meet all other conformance requirements of style sheets as described in this module.
Partial implementations
So that authors can exploit the forward-compatible parsing rules to assign fallback values, CSS renderers must treat as invalid (and ignore as appropriate) any at-rules, properties, property values, keywords, and other syntactic constructs for which they have no usable level of support. In particular, user agents must not selectively ignore unsupported component values and honor supported values in a single multi-value property declaration: if any value is considered invalid (as unsupported values must be), CSS requires that the entire declaration be ignored.
Implementations of Unstable and Proprietary Features
To avoid clashes with future stable CSS features, the CSSWG recommends following best practices for the implementation of unstable features and proprietary extensions to CSS.
Non-experimental implementations
Once a specification reaches the Candidate Recommendation stage, non-experimental implementations are possible, and implementors should release an unprefixed implementation of any CR-level feature they can demonstrate to be correctly implemented according to spec.
To establish and maintain the interoperability of CSS across implementations, the CSS Working Group requests that non-experimental CSS renderers submit an implementation report (and, if necessary, the testcases used for that implementation report) to the W3C before releasing an unprefixed implementation of any CSS features. Testcases submitted to W3C are subject to review and correction by the CSS Working Group.
Further information on submitting testcases and implementation reports can be found from on the CSS Working Group’s website at https://www.w3.org/Style/CSS/Test/. Questions should be directed to the public-css-testsuite@w3.org mailing list.
Index
Terms defined by this specification
- cascade, in § 2
- cascade origin, in § 2.2
- context, in § 2.1
- encapsulation contexts, in § 2.1
- importance, in § 2.3
- important, in § 2.3
- normal, in § 2.3
- origin, in § 2.2
- output of the cascade, in § 2.1
- @scope, in § 2.5.1
- scope, in § 2.5
- scoped descendant combinator, in § 2.5.2
- <scope-end>, in § 2.5
- scope proximity, in § 2.1
- <scope-start>, in § 2.5
- scoping limit, in § 2.5
- <selector-scope>, in § 2.5.3
- selector scoping notation, in § 2.5.3
- Strong Scoping Proximity, in § 2.1
- Weak Scoping Proximity, in § 2.1
Terms defined by reference
-
[css-cascade-5] defines the following terms:
- @import
- @layer
- all
- author origin
- cascade layers
- cascaded value
- declared value
- initial
- revert
- revert-layer
- unset
- user origin
- user-agent origin
-
[css-color-4] defines the following terms:
- plum
- teal
-
[css-scoping-1] defines the following terms:
- shadow host
- tree context
-
[css-syntax-3] defines the following terms:
- <stylesheet>
- at-rule
- block at-rule
- style rule
-
[css-values-3] defines the following terms:
- ?
-
[DOM] defines the following terms:
- shadow tree
- shadow-including tree order
-
[FETCH] defines the following terms:
- cors protocol
-
[HTML] defines the following terms:
- img
-
[selectors-4] defines the following terms:
- :is()
- :scope
- :scope element
- <forgiving-selector-list>
- complex selector
- descendant combinator
- scoped selector
- scoping element
- scoping root
- selector
- subject
References
Normative References
- [CSS-ANIMATIONS-1]
- Dean Jackson; et al. CSS Animations Level 1. 11 October 2018. WD. URL: https://www.w3.org/TR/css-animations-1/
- [CSS-CASCADE-5]
- Elika Etemad; Miriam Suzanne; Tab Atkins Jr.. CSS Cascading and Inheritance Level 5. 3 December 2021. WD. URL: https://www.w3.org/TR/css-cascade-5/
- [CSS-SCOPING-1]
- Tab Atkins Jr.; Elika Etemad. CSS Scoping Module Level 1. 3 April 2014. WD. URL: https://www.w3.org/TR/css-scoping-1/
- [CSS-SYNTAX-3]
- Tab Atkins Jr.; Simon Sapin. CSS Syntax Module Level 3. 16 July 2019. CR. URL: https://www.w3.org/TR/css-syntax-3/
- [CSS-TRANSITIONS-1]
- David Baron; et al. CSS Transitions. 11 October 2018. WD. URL: https://www.w3.org/TR/css-transitions-1/
- [CSS-VALUES-3]
- Tab Atkins Jr.; Elika Etemad. CSS Values and Units Module Level 3. 6 June 2019. CR. URL: https://www.w3.org/TR/css-values-3/
- [DOM]
- Anne van Kesteren. DOM Standard. Living Standard. URL: https://dom.spec.whatwg.org/
- [FETCH]
- Anne van Kesteren. Fetch Standard. Living Standard. URL: https://fetch.spec.whatwg.org/
- [RFC2119]
- S. Bradner. Key words for use in RFCs to Indicate Requirement Levels. March 1997. Best Current Practice. URL: https://datatracker.ietf.org/doc/html/rfc2119
- [SELECT]
- Tantek Çelik; et al. Selectors Level 3. 6 November 2018. REC. URL: https://www.w3.org/TR/selectors-3/
- [SELECTORS-4]
- Elika Etemad; Tab Atkins Jr.. Selectors Level 4. 21 November 2018. WD. URL: https://www.w3.org/TR/selectors-4/
Informative References
- [CSS-COLOR-4]
- Tab Atkins Jr.; Chris Lilley; Lea Verou. CSS Color Module Level 4. 15 December 2021. WD. URL: https://www.w3.org/TR/css-color-4/
- [CSS-NESTING-1]
- Tab Atkins Jr.; Adam Argyle. CSS Nesting Module. 31 August 2021. WD. URL: https://www.w3.org/TR/css-nesting-1/
- [HTML]
- Anne van Kesteren; et al. HTML Standard. Living Standard. URL: https://html.spec.whatwg.org/multipage/
Issues Index
querySelector()
.
Is this something we want to have? ↵