Skip to content

[css-cascade-7] @sheet proposal #11509 #11980

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 3 commits into
base: main
Choose a base branch
from
Open
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
319 changes: 319 additions & 0 deletions css-cascade-7/Overview.bs
Original file line number Diff line number Diff line change
@@ -0,0 +1,319 @@
<pre class='metadata'>
Title: CSS Cascading and Inheritance Level 7
Shortname: css-cascade
Level: 7
Status: ED
Prepare for TR: no
Work Status: Revising
Group: csswg
ED: https://drafts.csswg.org/css-cascade-7/
Previous Version: https://www.w3.org/TR/2021/WD-css-cascade-6-20211221/
Editor: Elika J. Etemad / fantasai, Apple, http://fantasai.inkedblade.net/contact, w3cid 35400
Editor: Miriam E. Suzanne, Invited Expert, http://miriamsuzanne.com/contact, w3cid 117151
Editor: Tab Atkins Jr., Google, http://xanthir.com/contact/, w3cid 42199
Editor: Kurt Catti-Schmidt, Microsoft, [email protected], w3cid 146156
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.
Abstract:
Abstract: New in this level is [[#at-ruledef-sheet]].
Ignored Terms: auto, flex items, <supports-condition>, <declaration>, scope proximity, encapsulation context
Informative Classes: ex
</pre>

<pre class=link-defaults>
spec:dom; type:dfn;
text:shadow tree
for:tree; text:root
text:shadow root; for:/
spec:dom; type:dfn; text:parent element
spec:css-color-4; type:property; text:color
spec:css-values-3; type: value; text:ex
spec:css-conditional-3; type:at-rule; text:@media
spec:mediaqueries-4; type:type; for:@media; text:all
spec:mediaqueries-4; type:type; text:<media-query>
spec:selectors-4; type:dfn; text:subject
spec:selectors-4; type:dfn; text:selector
spec:selectors-4; type:dfn; text:combinator
spec:html; type:element; text:style
spec:css-scoping-1; type:dfn; text:shadow host
</pre>

<pre class=ignored-specs>
spec:mediaqueries-5
spec:css-values-4
spec:css-fonts-4
</pre>

<h2 id="intro" oldids='filtering,fragments,stages-examples,actual,used,computed,cascaded,declared,specified,value-stages,all-shorthand,aliasing,shorthand,content-type,import-processing,conditional-import,at-import,defaulting,initial-values,inheriting,defaulting-keywords,initial,inherit,inherit-initial,default'>
Introduction and Missing Sections</h2>

Issue: This is a diff spec over <a href="https://www.w3.org/TR/css-cascade-6/">CSS Cascading and Inheritance Level 6</a>.
It is currently an Exploratory Working Draft:
if you are implementing anything, please use Level 6 as a reference.
We will merge the Level 6 text into this draft once it reaches CR.

<!-- Big Text: Stylesheet

███▌ █████▌ █ ▐▌ █▌ █████▌ ███▌ █▌ █▌ █████▌ █████▌ █████▌
█▌ █▌ █▌ ▐▌ █ █▌ █▌ █▌ █▌ █▌ █▌ █▌ █▌ █▌
█▌ █▌ █ ▐▌ █▌ █▌ █▌ █▌ █▌ █▌ █▌ █▌
███▌ █▌ ▐▌█ █▌ ████ ███▌ █████▌ ████ ████ █▌
█▌ █▌ █▌ █▌ █▌ █▌ █▌ █▌ █▌ █▌ █▌
█▌ █▌ █▌ █▌ █▌ █▌ █▌ █▌ █▌ █▌ █▌ █▌ █▌
███▌ █▌ █▌ █████ █████▌ ███▌ █▌ █▌ █████▌ █████▌ █▌
-->

<h2 id='stylesheet-section'>
Stylesheet</h2>

A <dfn export>stylesheet</dfn>
is a collection of style rules.

These collections may exist as:
<ol>
<li>An instance of file with a .css extension and/or MIME type of "text/css" embedded within a document.
<li>Collection of CSS rules within a document.
<li>CSSOM Stylesheet objects.
<li>Any of the above may be subdivided into named stylesheets with the ''@sheet'' keyword.
</ol>

A <dfn>sheet-name</dfn> is a string identifying
inner named sheets within a stylesheet.

Syntactically, a stylesheet may include an explicit [=sheet-name=], and is represented
by the <<sheet-name>> in ''@sheet'' and ''@import'' rules,
which is a single <<ident>> token:

<pre class='prod'>
<dfn><<sheet-name>></dfn> = <<ident>>
</pre>

<h3 id="at-ruledef-sheet">
Named Stylesheets: the `@sheet` block at-rule</h3>

The ''@sheet'' [=block at-rule=]
assigns its child style rules to a particular named [=stylesheet=].
This sheet-assignment syntax is:

<pre class='prod'>
@sheet <<sheet-name>> {
<<rule-list>>
}
</pre>

Such ''@sheet'' block rules have the same restrictions and processing
as a [=conditional group rule=] [[CSS-CONDITIONAL-3]]
with a true condition.
Copy link
Collaborator

@kbabbitt kbabbitt Mar 24, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm unclear on why this sentence is in the spec - can you explain what it's intended to do beyond what's implied by the grammar for @sheet above? (Explanatory text of this sort would be a good use case for a "Note".)

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good call out. This essentially means "the rules within this block apply", which is what you'd want for @layer (which I copied it from), but crucially not what we want for @sheet.

I switched the 'true condition' to 'false condition' and added an example.


<div class=example>
For example, ''@sheet'' and ''@media'' can be mixed:

<pre class=lang-css>
@sheet framework {
h1, h2 { color: maroon; background: white;}

@media (prefers-color-scheme: dark) {
h1, h2 { color: red; background: black; }
}
}
</pre>
</div>

Note: ''@sheet'' [=block at-rules=] cannot be interleaved with ''@import'' rules.

<h3 id="sheet-declaration">
Declaring Named Stylesheets</h3>

Named stylesheets can be declared:

* using an ''@import'' rule with the ''from'' keyword
assigning the contents of the imported file into that sheet.
* using an [[#at-ruledef-sheet|@sheet block at-rule]],
assigning its child style rules into that sheet.

<h3 id="at-ruledef-sheet-block">
Subdividing Stylesheets: the `@sheet` block at-rule</h3>

<pre class='prod'>
@import [ <<string>> from ]?
[ <<url>> | <<string>> ]
[ layer | layer(<<layer-name>>) ]?
<<import-conditions>> ;

<dfn export>&lt;import-conditions></dfn> = [ supports( [ <<supports-condition>> | <<declaration>> ] ) ]?
<<media-query-list>>?</pre>

where:
* <<string>> ''from'' imports only the named sheet
with name <<string>> from the provided URL.

* the <<url>> or <<string>>
gives the URL of the style sheet to be imported.

* the optional ''layer'' keyword or ''layer()'' function
assigns the contents of the style sheet
into its own anonymous [=cascade layer=]
or into the named [=cascade layer=].

The layer is added to the layer order
even if the import fails to load the stylesheet,
but is subject to any [=import conditions=]
(just as if declared by an ''@layer'' rule wrapped
in the appropriate [=conditional group rules=]).

* the optional <<import-conditions>>
states the [=import conditions=] under which it applies.

<div class="example">
The following <a href="#conditional-import">conditional <css>@import</css> rule</a>
only loads the style sheet with a name of ``foo`` from ``narrow.css`` when the UA
<a href="https://www.w3.org/TR/css-conditional-3/#support-definition">supports</a> ''display: flex'',
and only applies the style sheet on a <a href="https://www.w3.org/TR/CSS2/media.html#media-types">handheld</a> device
with a <a href="https://www.w3.org/TR/mediaqueries-4/#width">maximum viewport width</a> of 400px.

<pre>@import foo from url("narrow.css") supports(display: flex) handheld and (max-width: 400px);</pre>
</div>

<div class="example">
The following layer imports load the style sheets named ``foo`` into
the ''framework.component'' layer, and an un-named layer, respectively:

<pre>
@import foo from url("tabs.css") layer(framework.component);
@import foo from url("override.css") layer;
</pre>
</div>

If a <<string>> is provided,
it must be interpreted as a <<url>> with the same value.

<div class="example">
The following lines are equivalent in meaning
and illustrate both ''@import'' syntaxes
(one with ''url()'' and one with a bare string):

<pre class='lang-css'>
@import "mystyle.css";
@import url("mystyle.css");
</pre>
</div>

<!--
████████ ████████ ██████
██ ██ ██ ██
██ ██ ██
██████ ██ ██
██ ██ ██
██ ██ ██ ██
████████ ██ ██████
-->

<h2 id="changes">
Changes</h2>

This appendix is <em>informative</em>.


<h3 id="additions-l6">
Additions Since Level 6</h3>

The following features have been added since
<a href="https://www.w3.org/TR/css-cascade-6/">Level 6</a>:

* The definition of a [=stylesheet=],
as described by a combination of <<scope-start>> and <<scope-end>> selectors.
* The ''@sheet'' rule for subdividing stylesheets

<h3 id="additions-l5">
Additions Since Level 5</h3>

The following features have been added since
<a href="https://www.w3.org/TR/css-cascade-5/">Level 5</a>:

* 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


<h3 id="additions-l4">
Additions Since Level 4</h3>

The following features have been added since
<a href="https://www.w3.org/TR/css-cascade-4/">Level 4</a>:

* 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.

<h3 id="additions-l3">
Additions Since Level 3</h3>

The following features have been added since
<a href="https://www.w3.org/TR/css-cascade-3/">Level 3</a>:

* 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-cascade-4#aliasing]].
<!--
* Added definition of how scoped styles would cascade
(deferred from Level 3)
-->

<h3 id="changes-2">
Additions Since Level 2</h3>

The following features have been added since
<a href="http://www.w3.org/TR/CSS2/cascade.html">Level 2</a>:

<ul>
<li>The 'all' shorthand
<li>The ''initial'' keyword
<li>The ''unset'' keyword
<li>Incorporation of animations and transitions into the <a>cascade</a>.
</ul>

<h2 class="no-num" id="acknowledgments">Acknowledgments</h2>

David Baron,
Tantek Çelik,
Keith Grant,
Giuseppe Gurgone,
Theresa O'Connor,
Florian Rivoal,
Noam Rosenthal,
Simon Sapin,
Jen Simmons,
Nicole Sullivan,
Lea Verou,
and Boris Zbarsky
contributed to this specification.

<h2 id="privacy">
Privacy Considerations</h2>

* 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.

<h2 id="security">
Security Considerations</h2>

* 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.

* 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 <a href="https://html.spec.whatwg.org/multipage/urls-and-fetching.html#content-type"><code>Content-Type</code> metadata</a>
(or any same-origin file if the host document is in quirks mode)
are <code>text/css</code>,
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.