Subscribe on changes!

Add `:local()` pseudo selector to SFC `<style scoped>`

avatar
Nov 15th 2021

What problem does this feature solve?

The :global() pseudo selector in SFC style scoped allows us to disable scoped styles for a selector.

Currently there is no option in <style scoped> to style something dependant on a selector that selects an element above the current component but still want to scope your styles.

My idea is to add a new :local() pseudo selector that makes this possible: an exception from the global scope.

Example use cases

Dark mode

Use a different color scheme depending on a dark class on the <html> element:

<style scoped>
:global(.dark) :local(.my-component) {
    color: #f2f2f2;
    background: black;
}
</style>

More general

Change the style of a component with local scoped style differently depending on a class in a parent:

<style scoped>
.card {
    border: 2px solid #ccc;
    border-radius: 10px;
    /* has no background-color */
}

:global(.has-background-image) :local(.card) {
    background-color: #f2f2f2;
}
</style>

Complementing the :deep() selector

<style scoped>
:global(.selector-of-some-parent) :local(.selector-scoped-to-current-component) { /* [...] */}
</style>

Basically the same as this, just in the other tree direction:

<style scoped>
.selector-scoped-to-current-component :deep(.selector-of-some-child) { /* [...] */}
</style>

Inspiration

The syntax :local() is the same as the the selector with the same name in CSS Modules.

Why CSS modules is no replacement

CSS modules are not compatible with SASS.

What does the proposed API look like?

Add a :local() pseudo selector that works analog to the selector with the same name in CSS Modules.

Changes are probabily mostly required inside compiler-sfc/src/stylePluginScoped.ts.

avatar
Nov 15th 2021

Please open a discussion or PR in the vuejs/rfcs repository for this.

avatar
Nov 15th 2021

@posva: Thanks, I created a discussion

I was aware of the rfcs but was confused by the wording in the issue helper:

The issue list is reserved exclusively for bug reports and feature requests.

There is also no mentioning of the rfcs. If that's something that should be mentioned I'm happy to add a pull request to the issue-helper repo.

Maybe that would help to prevent future confusion about the correct location for such kind of feature requests. I thought this change would not fall in the category of being too "substantial" — to use the wording from the vuejs/rfcs readme.

avatar
Aug 25th 2023

To anyone looking for an answer to themeing, I wrote this postcss plugin with a :local() psuedo-selector: https://gist.github.com/tommie/c0eefee636033ff48cda50f89e3ccefa