Skip to content

RFC: Scoped Style Attribute #901

Closed
Closed
@lukeed

Description

@lukeed

If this is the wrong place for this -- sorry! StackOverflow didn't seem like the right place to me.

Currently, the inclusion of any CSS within a style tag is considered scoped. The only way out of this is to wrap your selector(s) in :global(). This, however, gets to be fairly verbose when you want to wrap all selectors on the page.

<style>
:global(.foo) {
  text-align: center;
}
:global(.foo span) {
  font-size: 80%;
}
:global(.foo em) {
  color: pink;
}
.bar {
  text-align: right;
}
</style>
<!-- unscoped: ".foo *" -->
<!-- scoped: ".bar" -->

Arguably, the appeal of SFCs is encapsulating all component-relatives into the single file. Additionally, a core motivation of Svelte (imo) is to assist in the creation of vanilla apps (including HTML, CSS, JS) in a nicer, faster way. (We all know this, duh!)

I bring this up because, right now, devs are essentially penalized for using the SFC format --- the obvious format for Svelte --- with an additional 17 bytes of CSS per selector, and the only ways to avoid the penalty are cumbersome: keep all CSS in a styles/ dir or :global all the things.

Although rendering is fast AF, there's "penalty" for rendering the scoped attribute & additional bytes penalty for saving the scope assignment in bundle.

Proposition

I'd like to use Vue as inspiration & move the current behaviors under the scoped attribute for the style tag. Nothing would change, including the ability to "exit" the scope with the help of :global.

<style scoped>
:global(.foo) {
  text-align: center;
}
:global(.foo span) {
  font-size: 80%;
}
:global(.foo em) {
  color: pink;
}
.bar {
  text-align: right;
}
<!-- same as current -->
<style>
.foo {
  text-align: center;
}
.foo span {
  font-size: 80%;
}
.foo em {
  color: pink;
}
.bar {
  text-align: right;
}
<!-- all unscoped -->

Then, without scoped, Svelte would treat normal style contents as partial CSS files. By default, no "penalties" via bytes (& render time, lol) are suffered. Instead, Svelte concatenates the stylesheet, as is, via component assembly.

This also opens the door for CSS preprocessors down the road via the lang attribute... another hat tip to Vue.

I plan on opening another RFC for lang at a later time. 😄

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions