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

Allow scoped class to be passed to the child components #4843

Closed
AlbertMarashi opened this issue May 16, 2020 · 5 comments
Closed

Allow scoped class to be passed to the child components #4843

AlbertMarashi opened this issue May 16, 2020 · 5 comments

Comments

@AlbertMarashi
Copy link

AlbertMarashi commented May 16, 2020

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())

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>

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
image

Related issues:

Add any other context or screenshots about the feature request here.

@AlbertMarashi
Copy link
Author

I'll also add that attribs should be passed to child components by default, or at least some, such as class or tabindex, similar to how it's done in Vue.js - However, this may be a breaking change, and would be fine if this was not added

@AlbertMarashi
Copy link
Author

AlbertMarashi commented May 16, 2020

I will provide some thoughts as to why sveltejs/rfcs#13 is incomplete too. Firstly, I'd like to say that this is a useful feature that has been added, but doesn't address the fact of targeting sub-elements

<ChildComponent
  --border="3px solid blue"
  --borderRadius="10px"
  --placeholderColor="blue"
></ChildComponent>

Some issues with this:

  1. It's verbose, if you have to do this outside of an {#each} for multiple items it's not great.
  2. You can't target child elements of the child component effectively
  3. Writing CSS will feel more natural to users and having CSS in HTML feels hacky

I totally understand the reason for using CSS variables, and I think the addition to svelte is great, but it doesn't address the other concerns

@AlbertMarashi
Copy link
Author

AlbertMarashi commented May 16, 2020

I will also provide some thoughts as to why :global won't always work:
in here, if I want to target a specific element within a slot of a child component, it's not a great or easy thing to do when you're using a preprocessor

div :global(a){
   h1 {
      color: red;  // this will not work
   }
   h2 {
       color: blue; // this will not work
   }
}

instead you must do something like

div :global(a h1){
   color: red;
}

div :global(a h2){
   color: blue;
}

which I feel is verbose, and additionally, you must wrap your child component in an element in order to target it (div in this case)

@pngwn
Copy link
Member

pngwn commented May 16, 2020

Although this has been discussed previously, at least this is a more detailed proposal.

This is a significant enough proposal both in terms of semantics and API that it warrants an RFC. Please make a pull request in https://github.com/sveltejs/rfcs where it can be discussed in full.

@pngwn pngwn closed this as completed May 16, 2020
@AlbertMarashi
Copy link
Author

AlbertMarashi commented May 17, 2020

Thanks @pngwn, will do

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

No branches or pull requests

3 participants