Re: [csswg-drafts] [css-cascade-6] Strong vs weak scoping proximity (#6790)

The question is "which behavior should we settle on", so we can actually start an experimental implementation.

> I think this isn't a question we should resolve one way or the other until we have plenty of feedback from the authoring perspective, and imho we should wait until cascade layers are usable so that the feedback on how scoping should work is in the context of already having layers.

That means delaying the entire scoping feature for a *significant* amount of time; half a year *at minimum*, probably 1-2 years realistically. I'm not sure what the connection is with layers, tho - both of the proposed placements for scope are underneath layers, either just above or just below specificity.

-------

Aside from the procedural matters, i think the proposed "scoped descendant" combinator has an obvious answer - it has to be weak (less than specificity) or else it'll be *incredibly* confusing. The example shows off the canonical use-case - "dueling selectors" where you have mutually nested containers with similar children, and want the rule with the closest indicated container to win in each case - and if scoping was stronger than specificity, it would mean that using the combinator like this would accidentally *also* block the ability for *any other code* to override those properties, which is absolutely an unintended and unwanted side effect. 

And I think it would be confusing if the two scoping mechanisms used different scoping positions, unless there was a *very* good reason for it (which I don't think there is).

-------

More generally, I still feel very strongly that the "weak scoping" placement (scoping is weaker than specificity, but stronger than order-of-appearance) is the correct place to insert it, for several reasons:

* One of the core complaints that people have had with specificity thruout CSS's history has been specificity wars - you style an element, then need to override it in some circumstances which needs a *more* specific selector, then need to override *that* in some circumstances which requires an *even more* specific selector. If your circumstances fall into the "general tag behavior, then class-specific, then element-specific", specificity works for you; if it doesn't (if this is just levels of classes with different *semantic* importance in your codebase), specificity fights you. In particular, this means that you shouldn't reach for an ID selector at first, for instance, even if it would be the most convenient way to target a particular element, unless you purposely intend for these styles to be *very strong* and hard to override. This has resulted in multiple CSS management strategies all basically concluding "don't ever use ID selectors", because once you do you're locked into using them in every subsequent rule targeting that element.

 If scoping was above specificity, this would be all of that but worse. The scope would make the styles more powerful than *any global rule*. Just like how using a single ID selector to target an element means you have to *always* use an ID selector to target that element, using scoping to style an element means you'd have to use scoping to *always* style the element, and you don't even have the flexibility of using a dummy ID on `body` or writing an ID selector twice; you *must* target the *same* scoping element, or something closer. And worse - if it's the same scoping element, then you *still* have to specificity-fight; if it's closer, then you've just done the equivalent of using *two* ID selectors, and the next one-off override has to scope *even tighter*.

* That's a holistic argument. A more specific one is - I can't think of any justification whatsoever why `@scope (.foo) { .bar {...}}` should win over `#bar`, when targetting the same element. ID selectors are *by their nature* selecting one specific element to put styles on, which is why a single one automatically wins over any other selectors in any quantity. The additional constraint of a scoping element doesn't make a general selector (like `.bar`) more specific (in the general sense, not the CSS term-of-art sense) than a selector explicitly targeting one single element specifically (like `#bar`).

 But if scoping is weaker than IDs, it's either weaker than *all* specificity, or it's inserted into the middle of the specificity tuple. I think the latter has far more confusion potential, especially when considered in light of the specificity-altering pseudo-classes (which presumably would *not* be able to alter the scope of a selector!).

* The *potential* use-cases for scoping cover a broad range of things, from "I want to write baseline styles, then have all context-specific styles automatically win without worrying about specificity on either side" (already covered, better, by layers), to "I want to write generic styles for this container, but have a particular instance work differently" (already covered by existing specificity), to "I have clashing styles, but want the styles that are 'closest' to the element to work, regardless of how things get nested" (the canonical scoping use-case). We should let scoping do what only it can do, and leave the other problems to the other solutions, rather than trying to interweave them; mixing solutions can easily produce author confusion.

*  The *other* part of scoping is the lower-boundary protection, to prevent your container styles from "leaking out" further. This is only tangentially connected to any notion of style strength within the container, so authors can easily want one without the other. If scoping is relatively strong, tho, then they *must* take it into account when considering whether to use this functionality for lower-boundaries as well; if it's relatively weak, then they can usually ignore it and consider the two halves separately. In particular, with the strength set to "just higher than order-of-appearance", they can pretty much *completely* ignore it if they want; since order-of-appearance is almost always just a meaningless tiebreaker rather than a semantic decision, aka random noise that they'll use specificity to fix if necessary, anything else operating at approximately that level is random noise as well if they're not paying attention to it, and the same fixes apply.

 If scoping operates at any higher point, then we should really disconnect it from lower-boundaries, to avoid confusion when people just want one of them. But that would be fairly sad, and imo itself somewhat confusing, since they operate in such similar semantic space.

-- 
GitHub Notification of comment by tabatkins
Please view or discuss this issue at https://github.com/w3c/csswg-drafts/issues/6790#issuecomment-959733391 using your GitHub account


-- 
Sent via github-notify-ml as configured in https://github.com/w3c/github-notify-ml-config

Received on Wednesday, 3 November 2021 17:00:57 UTC