-
Notifications
You must be signed in to change notification settings - Fork 706
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
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change | ||||||
---|---|---|---|---|---|---|---|---|
|
@@ -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>> ) ] | ||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe 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) There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. But There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Ok, that is intentional then. Sorry! =) There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Shouldn't this then be I'd rather not have authors needing to remember:
There was a problem hiding this comment. Choose a reason for hiding this commentThe 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><supports-import-condition></dfn> = [ supports( [ <<supports-condition>> | <<declaration>> ] ) ] | ||||||||
<dfn export><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. | ||||||||
Comment on lines
+125
to
+130
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I see the reasoning behind this, and think it's probably the best behavior - but it is a departure from There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Is it correct that wrapping an entire stylesheet's contents with I am unsure if that is the best option. If the behavior is different it also implies that bundling becomes impossible, which might make the entire feature unusable in practice as it would force CSS authors to serve unbundled stylesheets and take the associated performance hit. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Fair points. It sounds like this does in fact deserve it's own issue. :) There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
I'm not sure I do (anymore). I remember concluding that anything else was impossible, but I don't remember why. We'd have to allow relative selectors top-level, but we could do that and spec that they are relative against (Re-interpreting |
||||||||
|
||||||||
* 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– or feature-support–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. | ||||||||
|
||||||||
<!-- | ||||||||
██████ ███ ██████ ██████ ███ ████████ ████████ | ||||||||
██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ | ||||||||
|
@@ -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>) | ||||||||
|
||||||||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Need
layer-empty
added to theoldids
on line 46, or this PR doesn't build