4

In Svelte I can pass a custom class to a children component like that:

Icon.svelte

<script>
  export { className as class };
  
  let className = '';
</script>

<img src='...' class={className} />

App.svelte

<script>
  import Icon from './Icon/Icon'
</script>

<div id='app'>
  <Icon class='custom-icon' />
</div>

If I inspect the rendered DOM I see that the class is successfully given to the Icon component:

<img src='...' class='custom-icon' />

But if I define some style for .custom-icon in App.svelte they are not applied:

<script>
  import Icon from './Icon/Icon'
</script>

<style>
  .custom-icon {
    border: solid 2px red;
  }
</style>

<main>
  <Icon class='custom-icon' /> <!-- Icon has no red border -->
</main>

Check the codesandbox.

So has someone an idea how I can style a children component from the parent using a class?

johannchopin
  • 13,720
  • 10
  • 55
  • 101
  • Does this answer your question? [How to target a component in svelte with css?](https://stackoverflow.com/questions/56988717/how-to-target-a-component-in-svelte-with-css) – Zach Saucier Jan 02 '23 at 19:13

3 Answers3

4

I think there's a way to get the best of both worlds.

* :global(.custom-icon) {
   border: solid 2px red;
}

This will output a CSS like this:

.svelte-5z4ccp .custom-icon {
   border: solid 2px red;
}

This will allow you to have scoped CSS for the descendants of your component. It's not possible to scope it only for the immediate child, though, only to all the descendants.

Carlos Roso
  • 1,435
  • 1
  • 11
  • 14
2

try this

:global(.custom-icon) {
    border: solid 2px red;
}

see also https://svelte.dev/docs#style

2

You have two options:

  • define the styles you'll be using inside the child component where they will be used (see REPL) - these styles will be scoped to the component

or

  • define the styles with the :global modifier, making them available to all descendants of the component where the styles are defined (see REPL) - these styles will be unscoped
Thomas Hennes
  • 9,023
  • 3
  • 27
  • 36
  • Hey thanks for your response. Not a fan from you first point since I want the parent to fully customize the children (so I'm not supposed to predict it). For the second option you didn't mention that it makes styles available to all the app, not just the `descendants of the component`. So if I have an other `.custom-icon` in my app it will also be impacted. – johannchopin Jul 20 '20 at 14:48
  • Yes, that was implied by '*these styles are unscoped*'. I pointed out that the styles would be available to all descendants because that's where you would want to use them, but they will indeed be available throughout the app, sorry if this was not clear. – Thomas Hennes Jul 20 '20 at 17:01
  • Just to be clear, you cannot have the best of both worlds. Either your styles are scoped, but then they must be known at build-time, *or* you want to define them during run-time, in which case they cannot be scoped and you risk name collision. – Thomas Hennes Jul 20 '20 at 17:08
  • An alternate solution to style at run-time while avoiding name collision issues would be to use inline styles rather than CSS classes. – Thomas Hennes Jul 20 '20 at 17:10
  • Thats sad concerning svelte but seems to have no choice. I will use the global solution. Thanks again for your help. – johannchopin Jul 20 '20 at 17:12