Skip to content

Ability to bind a child component's root node(s) and apply CSS rules to them #4671

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

Closed
gotofritz opened this issue Apr 14, 2020 · 2 comments
Closed

Comments

@gotofritz
Copy link

gotofritz commented Apr 14, 2020

(First of all: thanks for the effort in creating and sharing this great piece of work)

Is your feature request related to a problem? Please describe.
Several in fact, it's something that comes up quite often

  • Using 3rd party icon libraries: how can I change colour on hover, for example?
  • Grid layouts: how do I assign a grid-area to a a 3rd party component?
  • I import a component and want to apply a CSS filter to blend it with the parent

In general I find this idea that parents "have no business in changing the CSS of child components" (cit.) a bit absurd. CSS's cascade doesn't allow extending or inheriting props in the OOP sense, that doesn't mean a parent component has 'no business' in controlling some of its CSS properties. After all if I add it to my component tree I am already controlling it. I can change its size and turn it upside down with a css transform, for example. But somehow reaching inside and changing the font colour of one of its parts is a no-no...?

Describe the solution you'd like
Some sort of notation that allows you to extend the CSS of the

<script>
import { PragmaticIcon } from 'some-3rd-party-icon-pack';

<style>
.root {
  grid-template-rows: 1fr 2fr;
  grid-template-areas: 'home away';
}
.something-else { 
  grid-area: home;
}
:host(PragmaticIcon) {
  grid-area: away;
}
:host(PragmaticIcon):hover svg {
  color: blue;
}
:host(PragmaticIcon) svg {
  color: red;
}
</style>

<div class="something-else">home</div>
<PragmaticIcon />

Describe alternatives you've considered
This goes quite far, but cannot be used to set the :hover style, for example

<script>
import { FormalistIcon } from 'some-3rd-party-icon-pack';

let domNodeComponentContainer;
  onMount(() => {
    // This makes the fg of the main img svg the inverse of the bg
    domNodeComponentContainer.querySelector('svg').style.cssText +=
      '; color: white; mix-blend-mode: difference; ';
  });
<style>
...
</style>

<div id="icon-container" bind:this={domNodeComponentContainer}>
  <FormalistIcon />
</div>

How important is this feature to you?
Fairly, but it's not life and death stuff

Additional context
I have seen previous vaguely related conversations, but I don't agree with the conclusions and since some time has passed I would kindly ask you to reconsider

#4443

@Conduitry
Copy link
Member

One of the restrictions with Svelte's styles is that the <style> block in a component needs to be compilable to static CSS without referring to any other components. Something like :host(FooComponent) .some-selector won't work because we won't know what to compile that to. There's no CSS selector that refers only to child elements within a given child component.

The way to solve all of these problems, if the component itself doesn't provide props or CSS variables or another way to do the customization you need, is to use partially global selector, as shown here. .some-container :global(.some-selector) will match all instances of .some-selector that appear anywhere as a descendant of instances of .some-container that appear within this component. If you want to be able to select particular elements within a child component, there needs to be a wrapper DOM element that you can refer to using CSS selectors.

@gotofritz
Copy link
Author

Thanks @Conduitry - I did discover that and I meant to update the ticket, thanks for closing it!

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

2 participants