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] Add a media() function for @import #10972

Open
romainmenke opened this issue Sep 28, 2024 · 3 comments
Open

[css-cascade-6] Add a media() function for @import #10972

romainmenke opened this issue Sep 28, 2024 · 3 comments

Comments

@romainmenke
Copy link
Member

#7348 (comment)

Media query lists can be partially valid.

This means that any @import that has both a media query list of at least two parts and any unknown condition will just swallow that unknown part as if it were an invalid media query.

https://codepen.io/romainmenke/pen/QWebVmp

@import url("foo.css") screen, screen does-not-exist();
@import url("foo.css")  does-not-exist() screen, screen;

In either case screen does-not-exist() forms an invalid media query and the media query list will always be a singular screen.

Ideally we want unknown parts to invalidate the entire @import, not the first or last media query in a media query list.


Proposal

Should we have a media() function to mirror scope(), supports(), ... ?
Wrapping it in a function makes it unambiguous what is part of a media query and what is not.

@import statements with both a media() function and a bare media query list should not be allowed. Bare media queries could even be marked as a "legacy syntax" and authors could be advised not to use it.

This function itself would suffer from the same problem it is trying to address but this would be a short term pain.

Because it is purely syntactic sugar we can transpile with tooling and authors could adopt this quickly.


Workaround

Any media query list can be split into multiple import statements:

@import url("foo.css") screen;
@import url("foo.css") screen does-not-exist();

/* two imports for `screen` don't make sense in practice, but imagine something more creative and useful */

I think this is also fine and we can have tooling to help authors (lint rules, ...)
Drawback is that it isn't obvious that you sometimes need to do this and authors shouldn't need to use tool.

Even less obvious when you can clean this up.
At some point all end users of a project will support the newly added syntax and the statements can be joined again.


I prefer a new media() function as this doesn't have any sharp edges and gives a nice parallel between the other import conditions.

@andruud
Copy link
Member

andruud commented Nov 7, 2024

+1 to this.

@import statements with both a media() function and a bare media query list should not be allowed.

Additionally, I assume we'd probably want to not allow mixing of "new stuff" (just scope(), at the moment) and bare MQ.

Without media(), we'll at least need to say that MQs always go last, although I think media() is a better solution.

cc @mirisuzanne

@andruud andruud added the Agenda+ label Nov 7, 2024
@tabatkins
Copy link
Member

Yeah, I'll have to squint at the grammar to make sure that's enforceable, but if we could just branch it so an import either has a bare MQ or has all the new things (including media()), that would be ideal.

chromium-wpt-export-bot pushed a commit to web-platform-tests/wpt that referenced this issue Nov 14, 2024
This CL implements the ability to scope an entire stylesheet on import,
via the new scope() function. The CSSWG has resolved to add the scope()
function, but there is no spec yet. The WPTs are therefore marked as
tentative for now.

Note that this CL intentionally does not have parse-validity tests,
such as scope() combined with other features of the @import prelude
(e.g. layer(), media queries). This is because scope()'s "position"
in the prelude grammar has not been defined, and the WG instead resolved
allow full reordering of the conditions. This opens a new problem,
tracked by Issue 10972 [1]. In other words, parsing tests are
deferred until that issue is resolved. The WPTs in this only use
@import scope(...)", which is assumed to be valid regardless of the
outcome.

Since regular top-level selectors are not relative selectors,
they are not guaranteed to contain either '&' or ':scope'
like selector parsing nested under CSSNestingType::kNesting
or CSSNestingType::kScope (respectively). This means that selectors
at the top-level of an imported stylesheet are not guaranteed to
be scope-containing, so we need another way of enforcing
the in-scope [2] requirement of scoped selectors. This is effectively
done by always treating the last selector in a complex selector
as scope-containing.

Due to the same absence of '&' and ':scope' in the imported stylesheet,
rules can also be incorrectly handled as "easy" or
"covered by bucketing" even though they match in the context of a scope.
Addressed this by disabling the optimization when context.style_scope
is set.

[1] w3c/csswg-drafts#10972
[2] https://drafts.csswg.org/css-cascade-6/#in-scope

Bug: 369876911
Change-Id: I75bc3514d959c6762232bc769f844682ed4a50fd
aarongable pushed a commit to chromium/chromium that referenced this issue Nov 14, 2024
This CL implements the ability to scope an entire stylesheet on import,
via the new scope() function. The CSSWG has resolved to add the scope()
function, but there is no spec yet. The WPTs are therefore marked as
tentative for now.

Note that this CL intentionally does not have parse-validity tests,
such as scope() combined with other features of the @import prelude
(e.g. layer(), media queries). This is because scope()'s "position"
in the prelude grammar has not been defined, and the WG instead resolved
allow full reordering of the conditions. This opens a new problem,
tracked by Issue 10972 [1]. In other words, parsing tests are
deferred until that issue is resolved. The WPTs in this only use
@import scope(...)", which is assumed to be valid regardless of the
outcome.

Since regular top-level selectors are not relative selectors,
they are not guaranteed to contain either '&' or ':scope'
like selector parsing nested under CSSNestingType::kNesting
or CSSNestingType::kScope (respectively). This means that selectors
at the top-level of an imported stylesheet are not guaranteed to
be scope-containing, so we need another way of enforcing
the in-scope [2] requirement of scoped selectors. This is effectively
done by always treating the last selector in a complex selector
as scope-containing.

Due to the same absence of '&' and ':scope' in the imported stylesheet,
rules can also be incorrectly handled as "easy" or
"covered by bucketing" even though they match in the context of a scope.
Addressed this by disabling the optimization when context.style_scope
is set.

[1] w3c/csswg-drafts#10972
[2] https://drafts.csswg.org/css-cascade-6/#in-scope

Bug: 369876911
Change-Id: I75bc3514d959c6762232bc769f844682ed4a50fd
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/6012179
Commit-Queue: Anders Hartvoll Ruud <[email protected]>
Reviewed-by: Rune Lillesveen <[email protected]>
Cr-Commit-Position: refs/heads/main@{#1383152}
chromium-wpt-export-bot pushed a commit to web-platform-tests/wpt that referenced this issue Nov 14, 2024
This CL implements the ability to scope an entire stylesheet on import,
via the new scope() function. The CSSWG has resolved to add the scope()
function, but there is no spec yet. The WPTs are therefore marked as
tentative for now.

Note that this CL intentionally does not have parse-validity tests,
such as scope() combined with other features of the @import prelude
(e.g. layer(), media queries). This is because scope()'s "position"
in the prelude grammar has not been defined, and the WG instead resolved
allow full reordering of the conditions. This opens a new problem,
tracked by Issue 10972 [1]. In other words, parsing tests are
deferred until that issue is resolved. The WPTs in this only use
@import scope(...)", which is assumed to be valid regardless of the
outcome.

Since regular top-level selectors are not relative selectors,
they are not guaranteed to contain either '&' or ':scope'
like selector parsing nested under CSSNestingType::kNesting
or CSSNestingType::kScope (respectively). This means that selectors
at the top-level of an imported stylesheet are not guaranteed to
be scope-containing, so we need another way of enforcing
the in-scope [2] requirement of scoped selectors. This is effectively
done by always treating the last selector in a complex selector
as scope-containing.

Due to the same absence of '&' and ':scope' in the imported stylesheet,
rules can also be incorrectly handled as "easy" or
"covered by bucketing" even though they match in the context of a scope.
Addressed this by disabling the optimization when context.style_scope
is set.

[1] w3c/csswg-drafts#10972
[2] https://drafts.csswg.org/css-cascade-6/#in-scope

Bug: 369876911
Change-Id: I75bc3514d959c6762232bc769f844682ed4a50fd
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/6012179
Commit-Queue: Anders Hartvoll Ruud <[email protected]>
Reviewed-by: Rune Lillesveen <[email protected]>
Cr-Commit-Position: refs/heads/main@{#1383152}
chromium-wpt-export-bot pushed a commit to web-platform-tests/wpt that referenced this issue Nov 14, 2024
This CL implements the ability to scope an entire stylesheet on import,
via the new scope() function. The CSSWG has resolved to add the scope()
function, but there is no spec yet. The WPTs are therefore marked as
tentative for now.

Note that this CL intentionally does not have parse-validity tests,
such as scope() combined with other features of the @import prelude
(e.g. layer(), media queries). This is because scope()'s "position"
in the prelude grammar has not been defined, and the WG instead resolved
allow full reordering of the conditions. This opens a new problem,
tracked by Issue 10972 [1]. In other words, parsing tests are
deferred until that issue is resolved. The WPTs in this only use
@import scope(...)", which is assumed to be valid regardless of the
outcome.

Since regular top-level selectors are not relative selectors,
they are not guaranteed to contain either '&' or ':scope'
like selector parsing nested under CSSNestingType::kNesting
or CSSNestingType::kScope (respectively). This means that selectors
at the top-level of an imported stylesheet are not guaranteed to
be scope-containing, so we need another way of enforcing
the in-scope [2] requirement of scoped selectors. This is effectively
done by always treating the last selector in a complex selector
as scope-containing.

Due to the same absence of '&' and ':scope' in the imported stylesheet,
rules can also be incorrectly handled as "easy" or
"covered by bucketing" even though they match in the context of a scope.
Addressed this by disabling the optimization when context.style_scope
is set.

[1] w3c/csswg-drafts#10972
[2] https://drafts.csswg.org/css-cascade-6/#in-scope

Bug: 369876911
Change-Id: I75bc3514d959c6762232bc769f844682ed4a50fd
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/6012179
Commit-Queue: Anders Hartvoll Ruud <[email protected]>
Reviewed-by: Rune Lillesveen <[email protected]>
Cr-Commit-Position: refs/heads/main@{#1383152}
moz-v2v-gh pushed a commit to mozilla/gecko-dev that referenced this issue Nov 16, 2024
…hind a flag, a=testonly

Automatic update from web-platform-tests
[@scope] Support '@import scope(...)' behind a flag

This CL implements the ability to scope an entire stylesheet on import,
via the new scope() function. The CSSWG has resolved to add the scope()
function, but there is no spec yet. The WPTs are therefore marked as
tentative for now.

Note that this CL intentionally does not have parse-validity tests,
such as scope() combined with other features of the @import prelude
(e.g. layer(), media queries). This is because scope()'s "position"
in the prelude grammar has not been defined, and the WG instead resolved
allow full reordering of the conditions. This opens a new problem,
tracked by Issue 10972 [1]. In other words, parsing tests are
deferred until that issue is resolved. The WPTs in this only use
@import scope(...)", which is assumed to be valid regardless of the
outcome.

Since regular top-level selectors are not relative selectors,
they are not guaranteed to contain either '&' or ':scope'
like selector parsing nested under CSSNestingType::kNesting
or CSSNestingType::kScope (respectively). This means that selectors
at the top-level of an imported stylesheet are not guaranteed to
be scope-containing, so we need another way of enforcing
the in-scope [2] requirement of scoped selectors. This is effectively
done by always treating the last selector in a complex selector
as scope-containing.

Due to the same absence of '&' and ':scope' in the imported stylesheet,
rules can also be incorrectly handled as "easy" or
"covered by bucketing" even though they match in the context of a scope.
Addressed this by disabling the optimization when context.style_scope
is set.

[1] w3c/csswg-drafts#10972
[2] https://drafts.csswg.org/css-cascade-6/#in-scope

Bug: 369876911
Change-Id: I75bc3514d959c6762232bc769f844682ed4a50fd
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/6012179
Commit-Queue: Anders Hartvoll Ruud <[email protected]>
Reviewed-by: Rune Lillesveen <[email protected]>
Cr-Commit-Position: refs/heads/main@{#1383152}

--

wpt-commits: 8c083dd5f5cf5801b2ae298bec62fc55e9226d74
wpt-pr: 49178
jamienicol pushed a commit to jamienicol/gecko that referenced this issue Nov 18, 2024
…hind a flag, a=testonly

Automatic update from web-platform-tests
[@scope] Support '@import scope(...)' behind a flag

This CL implements the ability to scope an entire stylesheet on import,
via the new scope() function. The CSSWG has resolved to add the scope()
function, but there is no spec yet. The WPTs are therefore marked as
tentative for now.

Note that this CL intentionally does not have parse-validity tests,
such as scope() combined with other features of the @import prelude
(e.g. layer(), media queries). This is because scope()'s "position"
in the prelude grammar has not been defined, and the WG instead resolved
allow full reordering of the conditions. This opens a new problem,
tracked by Issue 10972 [1]. In other words, parsing tests are
deferred until that issue is resolved. The WPTs in this only use
@import scope(...)", which is assumed to be valid regardless of the
outcome.

Since regular top-level selectors are not relative selectors,
they are not guaranteed to contain either '&' or ':scope'
like selector parsing nested under CSSNestingType::kNesting
or CSSNestingType::kScope (respectively). This means that selectors
at the top-level of an imported stylesheet are not guaranteed to
be scope-containing, so we need another way of enforcing
the in-scope [2] requirement of scoped selectors. This is effectively
done by always treating the last selector in a complex selector
as scope-containing.

Due to the same absence of '&' and ':scope' in the imported stylesheet,
rules can also be incorrectly handled as "easy" or
"covered by bucketing" even though they match in the context of a scope.
Addressed this by disabling the optimization when context.style_scope
is set.

[1] w3c/csswg-drafts#10972
[2] https://drafts.csswg.org/css-cascade-6/#in-scope

Bug: 369876911
Change-Id: I75bc3514d959c6762232bc769f844682ed4a50fd
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/6012179
Commit-Queue: Anders Hartvoll Ruud <[email protected]>
Reviewed-by: Rune Lillesveen <[email protected]>
Cr-Commit-Position: refs/heads/main@{#1383152}

--

wpt-commits: 8c083dd5f5cf5801b2ae298bec62fc55e9226d74
wpt-pr: 49178
andruud added a commit to andruud/csswg-drafts that referenced this issue Nov 18, 2024
Note that the Media Query part still needs to appear last in the grammar
due to w3c#10972.
andruud added a commit to andruud/csswg-drafts that referenced this issue Nov 18, 2024
Note that the Media Query part still needs to appear last in the grammar
due to w3c#10972.
i3roly pushed a commit to i3roly/firefox-dynasty that referenced this issue Nov 20, 2024
…hind a flag, a=testonly

Automatic update from web-platform-tests
[@scope] Support '@import scope(...)' behind a flag

This CL implements the ability to scope an entire stylesheet on import,
via the new scope() function. The CSSWG has resolved to add the scope()
function, but there is no spec yet. The WPTs are therefore marked as
tentative for now.

Note that this CL intentionally does not have parse-validity tests,
such as scope() combined with other features of the @import prelude
(e.g. layer(), media queries). This is because scope()'s "position"
in the prelude grammar has not been defined, and the WG instead resolved
allow full reordering of the conditions. This opens a new problem,
tracked by Issue 10972 [1]. In other words, parsing tests are
deferred until that issue is resolved. The WPTs in this only use
@import scope(...)", which is assumed to be valid regardless of the
outcome.

Since regular top-level selectors are not relative selectors,
they are not guaranteed to contain either '&' or ':scope'
like selector parsing nested under CSSNestingType::kNesting
or CSSNestingType::kScope (respectively). This means that selectors
at the top-level of an imported stylesheet are not guaranteed to
be scope-containing, so we need another way of enforcing
the in-scope [2] requirement of scoped selectors. This is effectively
done by always treating the last selector in a complex selector
as scope-containing.

Due to the same absence of '&' and ':scope' in the imported stylesheet,
rules can also be incorrectly handled as "easy" or
"covered by bucketing" even though they match in the context of a scope.
Addressed this by disabling the optimization when context.style_scope
is set.

[1] w3c/csswg-drafts#10972
[2] https://drafts.csswg.org/css-cascade-6/#in-scope

Bug: 369876911
Change-Id: I75bc3514d959c6762232bc769f844682ed4a50fd
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/6012179
Commit-Queue: Anders Hartvoll Ruud <[email protected]>
Reviewed-by: Rune Lillesveen <[email protected]>
Cr-Commit-Position: refs/heads/main@{#1383152}

--

wpt-commits: 8c083dd5f5cf5801b2ae298bec62fc55e9226d74
wpt-pr: 49178
@cdoublev
Copy link
Collaborator

cdoublev commented Nov 28, 2024

As noted in #11237 (comment), defining <media()> = media(<media-query-list>) could be useful.

I do not know if if() intentionally uses media(<media-query>) but color: if(media(unknown): green) would be invalid, but not with media(<media-query-list>), if I am not mistaken. edit: never mind, the query is syntactically valid and evaluates to false (like, media(1), which would become media(not all)).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

5 participants