- From: Miriam Suzanne via GitHub <sysbot+gh@w3.org>
- Date: Fri, 18 Dec 2020 20:39:09 +0000
- To: public-css-archive@w3.org
mirisuzanne has just created a new issue for https://github.com/w3c/csswg-drafts: == [css-scoping] Proposal for light-dom scoping/namespacing with re-designed `@scope` rule == This would likely require additions to both [CSS Scoping](https://drafts.csswg.org/css-scoping/) and [CSS Cascade](https://drafts.csswg.org/css-cascade/). See my [full explainer](https://github.com/oddbird/css-sandbox/blob/main/src/scope/explainer.md) for more details. As I've been working on proposals around cascade layers & component queries, there is another aspect of "cascade modernization that comes up regularly: scope. I'm aware that there is some hesitancy on the issue, since the [initial specification][] was never implemented, and Shadow DOM was seen as a path forward (potentially a replacement). I think that time (and further development of Shadow-DOM) has helped clarify two quite different use-cases: 1. Total isolation of a DOM subtree/fragment from the host page, so that no selectors get in or out unless explicitly requested. 2. Lighter-touch component namespacing, and prioritization of "proximity" when resolving the cascade. Shadow-DOM addresses the first, but it comes with a lot of overhead that is required for "full isolation". Meanwhile authors rely on convoluted naming conventions (like [BEM][]) and JS tooling (such as [CSS Modules][], [Styled Components][], & [Vue Scoped Styles][]) for the second use-case… which has been thoroughly discussed in various forms: - [Bring Back Scope](https://github.com/w3c/csswg-drafts/issues/3547) - [Selector Boundaries](https://github.com/w3c/csswg-drafts/issues/5057) - [CSS Namespaces](https://github.com/w3c/csswg-drafts/issues/270) [initial specification]: https://www.w3.org/TR/css-scoping-1/ [BEM]: http://getbem.com/ [CSS Modules]: https://github.com/css-modules/css-modules [Styled Components]: https://styled-components.com/ [Vue Scoped Styles]: https://vue-loader.vuejs.org/guide/scoped-css.html ## Re-introducing `@scope <selector> { ... }` with a few adjustments… ### 1. Provide a "lower boundary" or "slot" syntax This would make it possible to scope fragments rather than entire DOM sub-trees. @giuseppeg [has suggested a syntax](https://github.com/w3c/csswg-drafts/issues/3547#issuecomment-524206816) that I think is a good starting-point for more bikeshed discussion: ```css @scope (from: .carousel) and (to: .carousel-slide-content) { p { color: red } } ``` In my mind, only the first ("from") clause should be required, and may not need explicit labeling. It would likely accept a single (complex) selector: ```css @scope (.media-block) { img { border-radius: 50%; } } ``` In terms of selector-matching, this would be the same as `.media-block img`, but with slightly different cascade implications (see below). The second ("to") clause would be optional, and accept a list of selectors that represent lower-boundary "slots" in the scope. The targeted lower-boundary elements are included in the scope, but their descendants are not: ```css @scope (.media-block) to (.content) { img { border-radius: 50%; } .content { padding: 1em; } } ``` Which would only match `img` and `.content` inside `.media-block` -- _but not if there is no intervening `.content` between the scope root and selector target_. This follows the current selector-scoping behavior of various popular tools. I'm not convinced that `to` is necessarily the right keyword (others have proposed `until`) or if we should even consider using a functional syntax, or calling calling the lower boundary "slots": ```css @scope root(.media-block) slots(.content) { /* ... */ } ``` More discussion would be useful. ### 2. Make the cascade effects of scoping much less intrusive (weighted below specificity) When scopes do overlap, it's useful to recognize the _proximity_ of a scope (inner scope takes precedence) in the cascade. This is not currently represented in CSS. Descendant selectors rely on source order rather than proximity: ```css /* link colors for light and dark backgrounds */ .light-theme a { color: purple; } .dark-theme a { color: plum; } ``` When these color themes are nested, the dark theme will always take precedence: ```html <div class="dark-theme"> <a href="#">plum</a> <div class="light-theme"> <a href="#">also plum???</a> </div> </div> ``` Both shadow DOM and the original spec give scoped context a very powerful impact on the cascade — overriding even specificity. The original spec also inverted scope-layering for `!important` declarations. This follows the logic of more highly-isolated use-cases, where there is more clear distinction between the inner scope and the outer host. But in the more common lightly-scoped cases, a more nuanced interplay between specificity and scope is helpful. Most existing tools only add minimal cascade weight to scoped selectors, like a single attribute selector. I propose re-adding "scope proximity" to the cascade specification _after/below_ selector specificity, but above/before source-order. That would help resolve our example above: ```css @scope (.light-theme) { a { color: purple; } } @scope (.dark-theme) { a { color: plum; } } ``` ```html <div class="dark-theme"> <a href="#">plum</a> <div class="light-theme"> <a href="#">purple</a> </div> </div> ``` While still allowing more _specific_ selectors to override scope when desired. If authors desire more layering impact similar to the initial spec, that is now available using [Cascade Layers](https://drafts.csswg.org/css-cascade-5/#layering) — and the two features can be combined. ## A path forward This still needs a lot of work, but my goal here is to open discussion around a path forward for light-DOM scope/namespacing. I have a much more detailed [explainer](https://github.com/oddbird/css-sandbox/blob/main/src/scope/explainer.md) for my thought-process — but there are a lot of open questions, and I'd like to: - gauge CSSWG interest before going deeper - get more people involved with fleshing out the details Happy for comments, thanks! Please view or discuss this issue at https://github.com/w3c/csswg-drafts/issues/5809 using your GitHub account -- Sent via github-notify-ml as configured in https://github.com/w3c/github-notify-ml-config
Received on Friday, 18 December 2020 20:39:11 UTC