Skip to content
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

[css-cascade-6] Support @import scope() syntax #11237

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
Open
Changes from all commits
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
226 changes: 226 additions & 0 deletions css-cascade-6/Overview.bs
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,227 @@ Introduction and Missing Sections</h2>
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.

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

<h2 id="at-import">
Importing Style Sheets: the ''@import'' rule</h2>

The <dfn>@import</dfn> rule allows users to import style rules from other style sheets.
If an ''@import'' rule refers to a valid stylesheet,
user agents must treat the contents of the stylesheet as if they were written in place of the ''@import'' rule,
with two exceptions:

* If a feature
(such as the ''@namespace'' rule)
<em>explicitly</em> defines that it only applies to a particular stylesheet,
and not any imported ones,
then it doesn't apply to the imported stylesheet.

* If a feature relies on the relative ordering of two or more constructs in a stylesheet
(such as the requirement that ''@namespace'' rules must not have any other rules other than
''@import'' preceding it),
it only applies between constructs in the same stylesheet.

<p class='example'>
For example, [=declarations=] in style rules from imported stylesheets interact with the cascade
as if they were written literally into the stylesheet at the point of the ''@import''.

Any ''@import'' rules must precede all other valid at-rules and style rules in a style sheet
(ignoring ''@charset'' and <a href="#layer-empty"><css>@layer</css> statement</a> rules)
and must not have any other valid at-rules or style rules between it and previous ''@import'' rules,
or else the ''@import'' rule is invalid.
The syntax of ''@import'' is:

<pre class='prod'>
@import [ <<url>> | <<string>> ]
[[ layer | layer(<<layer-name>>) ]
|| [ scope( [ (<<scope-start>>) ]? [ to (<<scope-end>>) ]? | <<scope-start>> ) ]
Copy link
Collaborator

Choose a reason for hiding this comment

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

- [ scope( [ (<<scope-start>>) ]? [ to (<<scope-end>>) ]? | <<scope-start>> ) ]
+ [ scope( [ [ (<<scope-start>>) ]? [ to (<<scope-end>>) ]? ]! | <<scope-start>> ) ]

(do not allow empty alternative)

Copy link
Member Author

Choose a reason for hiding this comment

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

But @import scope() is valid, though. It gives you an "implicit scope", i.e. equivalent to @scope { }.

Copy link
Collaborator

Choose a reason for hiding this comment

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

Ok, that is intentional then. Sorry! =)

Copy link
Member

Choose a reason for hiding this comment

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

Shouldn't this then be @import scope in parallel with @import layer?

I'd rather not have authors needing to remember:

valid invalid
@import layer @import layer()
@import scope() @import scope

Copy link
Member Author

Choose a reason for hiding this comment

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

@romainmenke Ah, yes, that's seems better.

|| <<supports-import-condition>>]?
<<media-import-condition>>?;

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

where:

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

and optionally:

* the ''layer'' keyword or ''layer()'' function,
which 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-ordering|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 ''scope()'' function,
which [=scopes=] the [=style rules=] within the stylesheet,
using the [=scoping roots=] and [=scoping limits=]
as described by [[#scope-limits]].

Note: While the [=style rules=] within the imported stylesheet
become [=scoped=],
they do not become [=nested style rule|nested=].
In particular,
top-level selectors are not re-interpreted as [=relative selectors=],
and the ''&'' pseudo-class maintains its non-nested behavior.

* the [=import conditions=],
<<supports-import-condition>> and <<media-import-condition>>,
which state the conditions under which the ''@import'' rule applies.

Issue(10972): Accept <<media-import-condition>> at any point
after the URL/string.

<div class="example">
The following <a href="#conditional-import">conditional <css>@import</css> rule</a>
only loads the style sheet 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 url("narrow.css") supports(display: flex) handheld and (max-width: 400px);</pre>
</div>

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

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

<div class="example">
The following imports a stylesheet, and scopes the style rules
to elements matching <code>.card</code>.

<pre>
@import url("card.css") scope(.card);
</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>

<h3 id=conditional-import>
Conditional ''@import'' Rules</h3>

<dfn export>Import conditions</dfn> allow the import to be media&ndash; or feature-support&ndash;dependent.
In the absence of any <a>import conditions</a>, the import is unconditional.
(Specifying ''@media/all'' for the <<media-query-list>> has the same effect.)
If the <a>import conditions</a> do not match,
the rules in the imported stylesheet do not apply,
exactly as if the imported stylesheet were wrapped in ''@media'' and/or ''@supports'' blocks with the given conditions.

<div class=example>
The following rules illustrate how ''@import'' rules can be made media-dependent:

<pre class='lang-css'>
@import url("fineprint.css") print;
@import url("bluish.css") projection, tv;
@import url("narrow.css") handheld and (max-width: 400px);
</pre>
</div>

User agents may therefore avoid fetching a conditional import
as long as the <a>import conditions</a> do not match.
Additionally, if a <<supports-condition>> blocks the application of the imported style sheet,
the UA <em>must not</em> fetch the style sheet (unless it is loaded through some other link)
and <em>must</em> return null for the import rule's CSSImportRule.styleSheet value
(even if it is loaded through some other link).

<div class="example">
The following rule illustrates how an author can provide fallback rules for legacy user agents
without impacting network performance on newer user agents:

<pre class='lang-css'>
@import url("fallback-layout.css") supports(not (display: flex));
@supports (display: flex) {
...
}
</pre>
</div>

The [=import conditions=] are given by
<<media-query-list>>, which is parsed and interpreted as a <a>media query list</a>,
and <<supports-condition>>, is parsed and interpreted as a [[supports query]].
If a <<declaration>> is given in place of a <<supports-condition>>,
it must be interpreted as a <<supports-decl>>
(i.e. the extra set of parentheses is implied)
and treated as a <<supports-condition>>.

<div class="example">
For example, the following two lines are equivalent:
<pre class='lang-css'>
@import "mystyle.css" supports(display: flex);
@import "mystyle.css" supports((display: flex));
</pre>
</div>

The evaluation and full syntax of the <a>import conditions</a>
are defined by the <a href="https://www.w3.org/TR/mediaqueries/">Media Queries</a> [[!MEDIAQ]]
and <a href="https://www.w3.org/TR/css-conditional/">CSS Conditional Rules</a> [[!CSS-CONDITIONAL-3]] specifications.

<h3 id=import-processing>
Processing Stylesheet Imports</h3>

When the same style sheet is imported or linked to a document in multiple places,
user agents must process (or act as though they do) each link
as though the link were to an independent style sheet.

Note: This does not place any requirements on resource fetching,
only how the style sheet is reflected in the CSSOM and used in specs such as this one.
Assuming appropriate caching,
it is perfectly appropriate for a UA to fetch a style sheet only once,
even though it's linked or imported multiple times.

The [=cascade origin=] of an imported style sheet is the [=cascade origin=] of the style sheet that imported it.

The <a>environment encoding</a> of an imported style sheet is the encoding of the style sheet that imported it. [[css-syntax-3]]

<h3 id='content-type'>
Content-Type of CSS Style Sheets</h3>

The processing of imported style sheets depends on the actual type of the linked resource:

* If the resource does not have <l spec=html>[=Content-Type metadata=]</l>,
the type is treated as <code>text/css</code>.
* If the host document is in [=quirks mode=],
and the host document's origin is [=same origin=]
with the linked resource [=/response's=] [=response/URL's=] origin,
the type is treated as <code>text/css</code>.
* Otherwise, the type is determined from its <l spec=html>[=Content-Type metadata=]</l>.

If the linked resource's type is <code>text/css</code>,
it must be interpreted as a CSS style sheet.
Otherwise, it must be interpreted as a network error.

<!--
██████ ███ ██████ ██████ ███ ████████ ████████
██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██
Expand Down Expand Up @@ -770,6 +991,11 @@ Changes since the 21 March 2023 Working Draft</h3>
Significant changes since the
<a href="https://www.w3.org/TR/2023/WD-css-cascade-6-20230321/">21 March 2023 Working Draft</a> include:

* Added the <code>@import scope()</code> syntax,
and the ability to specificy ''layer()'', ''scope()'', and ''supports()''
in any order.
(<a href="https://github.com/w3c/csswg-drafts/issues/7348">Issue 7348</a>)

* Allowed [=declarations=] directly within ''@scope''.
(<a href="https://github.com/w3c/csswg-drafts/issues/10389">Issue 10389</a>)

Expand Down