-
Notifications
You must be signed in to change notification settings - Fork 659
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] Can we use @scope
for style isolation?
#11002
Comments
What does "bleed" mean exactly in the context of this issue? |
With it I mean to stop inheritance at the set scoping limit (if any). |
Maybe a |
Is the intention that this would only change the behavior of property inheritance or would it also interact with selector matching? If it is only for inheritance, how is it different from Given: <style>
.root {
font-family: sans-serif;
--foo: 1px;
}
.foo {
color: blue;
--bar: 2px;
background: red;
}
@scope isolated (.root) {}
</style>
<div class="root">
<div class="foo">how do I look?</div>
</div> Some questions about
|
I might be wrong but I believe @bramus meant something like the following. Given: <style>
:root {
color: green;
}
@scope isolated (.root) to (.foo) {
:scope {
color: red;
}
}
</style>
<div class="root">
this text is red
<div class="foo">this text should be green</div>
</div>
|
We'll want to be careful about naming something like this. Isolation might imply to authors that styles from 'outside' won't inherit into the scope. That sort of isolation-from-outside by definition has to be handled from the DOM. We can't have some style rules blocking other style rules from matching the same elements. This feature is limited to scoping the declarations that are defined inside the scope rule, so they don't get out. But even then, I'm not sure how we would actually want this to work. When a non-scoped element 'slotted' into our scope is defaulting, and would normally inherit… now what? I would expect that I maybe inherit from the parent of the scope root or something like that? We ignore the styles on any elements in our scope, and inherit styles from elsewhere on the page. I think this is somewhat intuitive, and maybe what you're asking for? But I don't think it works with a selector-based scope. We inherit values from elements, not from declarations. What do we do with values that were applied from out-of-scope, but apply to in-scope elements? What if those values were discarded in the cascade? To do that consistently, we wouldn't be ignoring only the scoped declarations, we would also have to ignore un-scoped (or un-isolated) declarations that match in-scope elements. <style>
:root { color: green; }
.scope-root { color: teal; }
.in-scope { color: blue; }
@scope isolated (.scope-root) to (.foo) {
.in-scope { color: hotPink; }
}
</style>
<div class="scope-root">
This text is teal
<div class="in-scope">
<div class="foo">What color is this??</div>
<div>
</div>
I think the only way to make sense of this is that elements/properties need to opt out of inheritance explicitly - and specify a new place to get the value from. A new global I like that this syntax clarifies where the new default will come from. But this approach comes with a big limitation. The lower boundary elements are excluded from the scope, so they can't be styled from the 'same' scope as the styles we want to revert. It would not be possible to have all the lower-boundary selectors Maybe we should provide that anyway? See #8617 But I wonder if we really want (or also want) a way to 'inherit from named ancestor x'? |
Even with <style>
:root { color: green; }
.scope-root { color: teal; }
.in-scope { color: blue; }
@scope isolated (.scope-root) to (.foo) {
.in-scope { color: hotPink; }
:scope-end { color: revert-scope; }
}
</style>
<div class="scope-root">
This text is teal
<div class="in-scope">
<div class="foo">What color is this??</div>
<div>
</div> Since the color was never defined on |
Correct
I would say that intuitively it should be
I feel like that would be confusing, not because it's inheriting from an in-scope element, but because it's skipping the non-scoped
I agree, that's even more confusing Again, I might be wrong, but I believe that the original idea is to remove the isolated style declarations from the cascade for all elements outside specified scope, if that makes sense. |
The reasoning makes sense to me, but I don't know if the behavior would make sense in practice. It's sort of fundamentally not how inheritance works, which is to get the computed value on the parent after it's already been through the cascade etc. And in this case we'd be asking for a value that was never computed or applied anywhere, but is still coming from context. |
Thanks for the example @mirisuzanne. I hadn’t really thought of the situation where you’d have non-scoped styles targeting elements inside the created scope. It can be interpreted in many ways, leading to surprising results. |
I remember now what I was originally thinking when I proposed this. My line of thinking was that the subtree with
So the text in |
It doesn't seem to me like it's reasonable for some CSS to define what other CSS is allowed to style. I feel like that comes with all sort of spooky-action-at-a-distance implications. I can basically turn off all your existing styles by saying |
This is exactly what I was hoping was being proposed here. I recognize it seems like an exotic concept, but the existence of Shadow DOM style isolation shows that it's valuable in principle. And yes, that is dictated by the shape of the DOM, but it's exactly this restriction that makes it unwieldy and problematic. Zooming out, CSS decouples styling from the DOM. It uses information in the DOM but it's not really limited by it (I can select a class or a tag name or an id etc.). New concepts like @scope selectively apply rules to portions of the DOM and @layer provides explicit control over the order of the cascade. The isolation concept seems like a potentially logical next step. Decoupling isolation from an intrustive DOM feature (Shadow DOM) would be more expressive and flexible. If there's not some fundamental reason it's antithetical to the core design of CSS, it seems at least worth considering? |
I'm not arguing with the usefulness of isolation in relation to CSS. I get why it sounds useful. But… you're just entirely not worried about how this proposal allows some CSS to turn off all other CSS? Does that include browser defaults? What about user preferences? They aren't scoped. When I scope over a custom element, do I exclude shadow styles? Are important styles excluded as well? This feels like such a wildly powerful trump card, it requires a whole new cascade-of-scopes. I just have so many questions about how this would be done in a manageable way that doesn't lead to chaos. So I guess I'm interested in a fleshed-out proposal before I comment more? Maybe you all see a path forward that I'm just missing. |
This part doesn't seem too tricky to me. It's an author styles concept so it only applies to those (default and user would still apply). Shadow DOM is separately isolated so it's unchanged. Important doesn't penetrate since I think for properties this would act like
Yup, I share the concern. The isolation concept is inherently defensive and potentially implies that other style rules could be unknown "threats." This is probably a bad signal to send, although The recent additions of @layer and @scope seem more pro-actively oriented: I do something additive to "take control" of the cascade and region of influence. With this in mind, I think another direction we could go to achieve a similar level of expressiveness and flexibility would be to have more power about bringing a set of rules into a scope. So instead of
<link rel=stylesheet href=... layer=foo>
<style>
@scope (.foo) {
@mixin-layer(foo);
}
</style> If this seems like a more reasonable direction, it probably needs its own issue (and/or there are likely other relevant issues). |
I'm not sure how selective inclusion is different from isolation? Those seem the same to me, or else separate features. Treating an import (or a layer or a sheet) as a mixin is interesting, but unless the scope is isolated from un-scoped styles, I'm not sure it changes anything here. |
CSS
@scope
is for selector isolation, not style isolation. Properties that inherit will inherit onto children beyond the scope’s scoping limit. From a lot of authors I hear that they expected it to be about style isolation.I was wondering if it would be possible to extend
@scope
to do style isolation too – something I believe would be very helpful for web component authors.Maybe a prelude like
isolated
? E.g.@scope isolated (root) to (limit) { /* no authors styles get in or bleed out */ }
.Or maybe there need to be two flags? One to prevent styles from getting in, and one to prevent them from bleeding out?
The text was updated successfully, but these errors were encountered: