Open faceless2 opened 2 years ago
Yeah, this seems reasonable to me. Might quibble a bit on the syntax, but being able to apply a scope to the rules in a stylesheet seems at least as useful as being able to put a stylesheet on a particular cascade layer.
I think an easier way of handling scope in HTML would simply be:
<link rel="stylesheet" href="module.css" scope=".media-object to .content">
My proposal would be that both a scope()
function in CSS @import
, and a scope
attribute on the <link>
element could accept the full @scope
condition syntax:
@scope (.media-object) to (.content) inclusive { … }
@import url(module.css) scope((.media-object) to (.content) inclusive);
<link rel="stylesheet" href="module.css" scope="(.media-object) to (.content) exclusive">
The only edge case that might warrant a special-case is importing a scope with only the scope root. Without any exceptions, that would result in double-parentheses:
@import url(module.css) scope((.media-object));
I also want to recognize that adding attributes like this to HTML <link>
also requires our proposed (but not yet fully specified or approved) update to the <link media="">
attribute, so that it's possible to test for support of scoping, and only load the linked CSS file if the scoping will be applied. This is also needed for a proposed layer
attribute.
There's a PR in progress, but I could use help on some of the details.
The CSS Working Group just discussed scoping rules from @import
, and agreed to the following:
RESOLVED: add scope() to @import syntax
@mirisuzanne I see that you removed the https://github.com/w3c/csswg-drafts/labels/Needs%20Edits label a while ago, but there does not seem to be a commit that added text to the spec for this resolution. Could it be this label was removed by mistake?
@bramus yes that's possible, and seems likely - it accidentally got associated with implicit scope issue.
Where would the scope()
function be in the syntax of @import
relative to supports()
?
I am assuming it will not be placed before layer
, so either before or after supports()
?
I don’t think the order in which these are declared should matter. E.g. @import url(…) supports(…) scope(…)
and @import url(…) scope(…) supports(…)
should behave the same, no?
The order in which they are processed could be fixed though, similar to how the individual transform properties are applied in a predetermined order.
Currently the order does matter for the existing parts :
layer
supports()
Any other order is invalid today.
I agree that a non-fixed order between new import conditions would be good. Makes it easier for authors to get it right.
The order in which they are processed could be fixed though, similar to how the individual transform properties are applied in a predetermined order.
Probably good to specify this, but I don't think it can have observable side-effects if different browsers apply import conditions in different orders. (layer
must still be applied at a specific point relative to all the conditions, and this is specified)
The order also isn't specified today for supports()
and media query lists : https://drafts.csswg.org/css-cascade-5/#conditional-import
Unless I am overlooking it?
Do we need to put this back on the agenda to discuss the questions about ordering?
The CSS Working Group just discussed [css-cascade-6] Add ability to scope rules from an imported stylesheet
, and agreed to the following:
RESOLVED: allow full reordering of all the current conditions on @import (MQ, scope, ...)
RESOLVED: the WG recommends having an attribute to enable @scope on the HTML link element
Can we make it so that authors do not have to wrap simple scope conditions in extra parenthesis?
@imports "foo" scope(.foo); /* -> authors will want to write this */
@imports "foo" scope((.foo)); /* explicitly wrapped in parenthesis */
@imports "foo" scope((.foo) to (.bar));
allow full reordering of all the current conditions on @import (MQ, scope, ...)
There is an issue with allowing any order. Media query lists can be partially valid.
Any media query list with more than one media query would swallow unrecognized trailing parts.
@import url("foo") screen, print something-invalid(really-does-not-exist);
This still applies fine everywhere that matches screen
.
The same for:
@import url("foo") screen, print scope(.foo);
You can see this in action in this codepen:
https://codepen.io/romainmenke/pen/WNVvyBY
Can we instead just allow any order between new conditions?
layer
always firstEdit: it seems this problem already exists today even without allowing any order:
@import url("foo") scope(.foo) print, screen; /* "foo" is applied, even in browsers without support for `scope` conditions */
Updated example showing that unknown conditions are just ignored both before and after media query lists: https://codepen.io/romainmenke/pen/QWebVmp
So maybe this is fine?
If I remember correctly, @scope { /* styles */ }
to mean "scope to the parent of the style tag" is still a thing, would <link scope src="whatever">
work analogously then? That seems like something that could be convenient in practice.
@DarkWiiPlayer I agree that could be useful. We didn't clearly specify how it should work here, so probably should work through those details.
@romainmenke oh that's interesting.
This is following on from a brief conversation with @tabatkins at CSSDay.
While I like the scoping proposal, I think it really needs a way to scope styles from an imported stylesheet. As it is now you can define your scopes - great for modularization - but the rules have to be inline in the same sheet, which seems to defeat the purpose a bit to me.
There are several ways to do this - an
@import
inside a@scope
is one, but I think for consistency with cascade layers the syntax should be likeAlso useful but slightly more controversial (it doesn't have the desired behaviour when the attribute is not recognised) would be adding a
scope
and (pending a better idea) ascope-to
attribute to<link>
, the same way that it now haslayer
(see https://github.com/whatwg/html/pull/7658)