Description
I was directed to post this to the RFCs, so I am reposting this from. sveltejs/svelte#4843
I am posting here to get thoughts or pros/cons about the various solutions
Feature request description.
I think Svelte is missing an important feature that other frameworks like Vue have. We need a way to easily apply CSS to a child component from the parent without having to use the verbose selector :global(childSelector) {}
inside the CSS
We should be able to apply CSS via classes to child components from the parent element. This is a missing feature that should be in svelte.
Describe the solution you'd like
imagine <Link/>
is a component that renders an <a>
element and has some scripts for routing (eg: event.preventDefault()
), and you would like to style that <a>
element from the parent
Solution 1:
Add an attribute such as descendants or something to the <style>
element to let svelte know that these styles should apply to child components too
<Link href="/about">About Us</Link>
<style descendants>
// notice the descendants attributes (similar to how Vue has scoped
a {
color: red;
}
</style>
Solution 2:
Allow Child components to be given some sort of attribute that tells svelte to pass the scope to the child component, eg:
<Link:scoped/>
or
<Link scoped/>
<style>
a {
color: red;
}
</style>
Solution 3:
Allow targeting of components within the parent CSS. eg:
<style>
Link {
color: red;
}
// or
:component(Link) {
color: red;
}
</style>
Solution 4:
Get svelte to inject the component's unique scope ID as a class, which would allow nesting in preprocessors
<style lang="stylus">
:scope() a {
color: red;
}
// or
:scope() {
a {
color: red;
}
}
</style>
Output::
.svelte-123 a {
color: red;
}
Describe alternatives you've considered
I have considered taking the selector :global(childSelector){}
but it is far too verbose, especially if you have something like a <Link>
component for JavaScript routing, and it might be found in your nav, sidebar, content, headings, footer (with each instance styled differently)
Not to mention that this only works if you wrap the component in something (selector) otherwise it would apply the global everywhere, eg:
<div>
<Link href="/about">About Us</Link>
</div>
<style>
div :global(a) {
color: red;
}
</style>
I would like to do something like this:
<Link href="/about">About Us</Link>
<style descendants>
a {
color: red;
}
</style>
How important is this feature to you?
This is such an important issue that has been raised a number of times and I am begging the svelte team to consider adding anything like this.
I am willing to contribute adding these features if supported
Additional context
This issue has been raised many times:
@nikku summed this up perfectly
Related issues:
- RFC: Scoped Style Attribute svelte#901
- Support for components being able to impact css scope svelte#4661
- Passing CSS custom properties to components #13
- Styles get uncorrectly removed / how to pass down styles? svelte#4281
- Support classes on nested components svelte#2888
- Add the ability to add classes to slots svelte#4443
- Support global styles - Allow multiple top-level style tag declarations with different attributes svelte#2762
- Adding :scope pseudo-class support svelte#1450
- https://github.com/sveltejs/rfcs/blob/style-properties/text/0000-style-properties.md
Add any other context or screenshots about the feature request here.