-
-
Notifications
You must be signed in to change notification settings - Fork 4.2k
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
fix: use hybrid scoping strategy for consistent specificity increase #10443
Conversation
🦋 Changeset detectedLatest commit: 9312d55 The changes in this PR will be included in the next version bump. This PR includes changesets to release 1 package
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Code looks good!
We should note this in the list of breaking changes along with the regexp quickfix for backwards compatibility in case you need it (mentioning the selector specificity caveat).
Also: Is this in any way less performant (additional :where
wrappers could add up, I have no idea)? Is this measurable somehow?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
that changeset filename lol
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
😆
Added a note on the breaking change. I did some naive benchmarking locally and could find no performance impact, which I think makes sense |
The context for this is #9549, though I think it may also address #7991.
Today, Svelte uses class selectors to scope local styles to the component. In other words, this...
...is effectively turned into this, so that
<p>
elements outside the component are not affected by this component's styles:The wrinkle is that this affects the selector's specificity, in a way that could cause bugs — #1277 — unless we add redundant-looking duplicate class selectors so that the specificity increase is uniform within a component.
Unfortunately, this approach also has its flaws:
Happily, it's 2024, and we now have a way of scoping selectors without increasing specificity —
:where
.One approach would be to use
:where(.svelte-xyz)
everywhere instead of just.svelte-xyz
. We briefly tried that, but found that it violated people's expectations that component styles would be more specific than global styles that were appended to the document later. In practice, people want a specificity bump, they just want it to be predictable.Another approach would be to make it an option. This is what Astro does with
scopedStyleStrategy
, for example, but I'm not personally a fan of this sort of approach — it forces the developer to think about the problem, and yields subtle differences between different apps (which might affect e.g. component libraries that they use in common). (In Astro's case there's an option to use data attributes instead of classnames — this arguably yields cleaner markup, though when we've investigated this in the past we've found that class selectors have better performance, which eventually starts to matter. For now I think we should stick with classnames, though that could be decided independently of the:where
question.)So this PR proposes a third option — a hybrid approach, that uses a class selector exactly once per compound selector, for a uniform specificity bump of
+0-1-0
, and uses:where
for any subsequent selectors. As a bonus, it allows us to simplify the code a bit.Before submitting the PR, please make sure you do the following
feat:
,fix:
,chore:
, ordocs:
.Tests and linting
pnpm test
and lint the project withpnpm lint