Skip to content
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

@scope support #1358

Open
2 of 3 tasks
mindplay-dk opened this issue Apr 12, 2024 · 6 comments
Open
2 of 3 tasks

@scope support #1358

mindplay-dk opened this issue Apr 12, 2024 · 6 comments
Labels
feature request New feature or request

Comments

@mindplay-dk
Copy link

What would you want to propose?

I'd like to suggest support for @scope

Suggested solution

This is just an idea, I have no idea if this would work in general.

https://jsfiddle.net/mindplay/agd9k2p1/

So this:

@scope (.panel) to (.content) {
  h2 {
    color: red;
  }
}

Becomes this:

:where(.panel) h2:where(:not(.content h2)) {
  color: red;
}

And a more complex selector like this:

@scope ([scope=panel]) to ([scope]:not([scope=panel])) {
  h2 {
    color: red;
  }
  p {
    font-weight: bold;
  }
}

Becomes this:

:where([scope=panel]) h2:where(:not([scope]:not([scope=panel]) h2)) {
  color: red;
}

:where([scope=panel]) p:where(:not([scope]:not([scope=panel]) p)) {
  font-weight: bold;
}

So this would require both :where and :not, I think - to get the right specificity.

But this is just a rough idea - I'm not a CSS superhero, and I don't know if this is completely correct or scoped properly etc.

Additional context

Only a few browsers support this already.

https://caniuse.com/css-cascade-scope

But this would be an incredible feature, if we didn't have to wait 3-5 years for every browser to support it - we could basically stop using CSS frameworks, CSS-in-JS, Tailwind etc. would all essentially be obsolete (from my personal point of view!) and we could finally have something resembling component-scoped CSS natively in the browser without JavaScript. 😄

Validations

  • Follow our Code of Conduct
  • Check that there isn't already an issue that request the same feature to avoid creating a duplicate.

Would you like to open a PR for this feature?

  • I'm willing to open a PR
@mindplay-dk mindplay-dk added the feature request New feature or request label Apr 12, 2024
@romainmenke romainmenke changed the title @scope support @scope support Apr 12, 2024
@romainmenke
Copy link
Member

But this would be an incredible feature, if we didn't have to wait 3-5 years for every browser to support it - we could basically stop using CSS frameworks, CSS-in-JS, Tailwind etc. would all essentially be obsolete (from my personal point of view!) and we could finally have something resembling component-scoped CSS natively in the browser without JavaScript.

Yes! We don't use any of those things but we are equally excited about @scope and all the things it can do.

I've been following the specification work and as far as I know there is no way to have a full polyfill that is actually correct. But the same was said about cascade layers and we managed to ship that so, who knows :D


Cascade layers took several weeks of near full time work to get right and this will have a similar level of complexity. A lot of that time is research, testing, ...

I don't really want to create this for free :)

I've set a sponsorship goal, if this is met I am willing to start work on this :
https://github.com/sponsors/csstools/

@phaux
Copy link

phaux commented Jun 5, 2024

I wonder if this is even possible to transpile considering that scope conflicts are resolved by proximity to the scope root:

@scope adds a new criterion to the CSS cascade: scoping proximity. This states that when two scopes have conflicting styles, the style that has the smallest number of hops up the DOM tree hierarchy to the scope root is applied.

https://developer.mozilla.org/en-US/docs/Web/CSS/@scope#how_scope_conflicts_are_resolved

@romainmenke
Copy link
Member

Yes, that is the largest unknown.

@phaux
Copy link

phaux commented Jun 5, 2024

Something like this could work:

Before:

@scope (.light-theme) {
  :scope {
    background-color: #ccc;
  }
  p {
    color: black;
  }
}

@scope (.dark-theme) {
  :scope {
    background-color: #333;
  }
  p {
    color: white;
  }
}

After:

.light-theme {
  background-color: #ccc;

  > p,
  > * > p,
  > * > * > p,
  > * > * > * > p,
  > * > * > * > * > p {
    color: black;
  }
}

.dark-theme {
  background-color: #333;

  > p,
  > * > p,
  > * > * > p,
  > * > * > * > p,
  > * > * > * > * > p {
    color: white;
  }
}

@mindplay-dk
Copy link
Author

@phaux interesting. this would work up to n levels of nesting only though, then it falls apart, correct?

This wouldn't be great for file size, but it'll probably compress pretty well.

I wonder about the performance of evaluating all these selectors though? 🤔

@Wdestroier
Copy link

If that helps, postcss-scope-polyfill supports the simple use case. Requires the CSS @scope polyfill.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
feature request New feature or request
Projects
None yet
Development

No branches or pull requests

4 participants