Reputation: 1141
How would I do something like this:
<style>
Nested {
color: blue;
}
</style>
<Nested />
i.e. How do I apply a style to a component from its parent?
Upvotes: 40
Views: 26940
Reputation: 522
Similar to pgalle's answer & Johannes's answer:
<style>
.wrapper > :global(*){
color: blue;
}
</style>
<div class="wrapper">
<Nested class="nested"/>
</div>
<style>
.wrapper > :global(.nested){
color: blue;
}
</style>
<div class="wrapper">
<Nested class="nested"/>
<Nested/>
</div>
Nested.svelte:
<div class={$$props.class} />
<style>
:global(.ss-ReplaceWithRandom){
color: blue;
}
</style>
<Nested class="ss-ReplaceWithRandom"/>
<Nested/>
Nested.svelte:
<div class={$$props.class} />
<style>
* + :global(*){
color: blue;
}
</style>
<template />
<Nested/>
Upvotes: 1
Reputation: 1530
The only way I can think of is with an additional div
element.
App.svelte
<script>
import Nested from './Nested.svelte'
</script>
<style>
div :global(.style-in-parent) {
color: green;
}
</style>
<div>
<Nested />
</div>
Nested.svelte
<div class="style-in-parent">
Colored based on parent style
</div>
Multiple Nested elements
You could even allow the class name to be dynamic and allow for different colors if you use multiple Nested
components. Here's a link to a working example.
Upvotes: 16
Reputation: 675
Update for 2023, you can wrap your style tags in svelte:head which will put them in the head, removing them from the scope context.
<svelte:head>
<style>
div { color: red };
</style>
</svelte:head>
This snippet will make all div elements have the color "red". As such, I'd recommend using this sparingly (I'd probably only use it for scripts/content in a legacy way). Only because debugging "why is everything red" will be impossible for projects with significant routes.
The, iirc, "documented" way is through CSS variables.
<!-- Nested.svelte -->
<div>
<slot />
</div>
<style>
div { color: var(--nested-color, inherit); }
</style>
===
<!-- Parent.svelte -->
<div>
<Nested>
Applesauce
</Nested>
</div>
<style>
div {
--nested-color: red;
}
</style>
Upvotes: 6
Reputation: 304
The way I do it is like this:
<style lang="stylus">
section
// section styles
:global(img)
// image styles
</style>
This generates css selectors like section.svelte-15ht3eh img
that only affects the children img tag of the section tag.
No classes or tricks involved there.
Upvotes: 1
Reputation: 169
You could use inline styles and $$props...
<!-- in parent component -->
<script>
import Nested from './Nested.svelte';
</script>
<Nested style="background: green; color: white; padding: 10px; text-align: center; font-weight: bold" />
<!-- in Nested.svelte -->
<script>
let stylish=$$props.style
</script>
<div style={stylish}>
Hello World
</div>
Upvotes: 12
Reputation: 411
using :global(*)
is the simplest solution.
No need to specify a class in the child if you want to style all immediate children for example
In the parent component:
<style>
div > :global(*) {
color: blue;
}
<style>
<div>
<Nested />
<div>
Nested will be blue.
Upvotes: 9
Reputation: 8346
You need to pass props to the parent component with export let, then tie those props to class or style in the child component.
You can either put a style tag on the element in the child you want to style dynamically and use a variable you export for the parent to determine the value of a style directly, then assign the color on the tag like this:
<!-- in parent component -->
<script>
import Nested from './Nested.svelte';
</script>
<Nested color="green"/>
<!-- in Nested.svelte -->
<script>
export let color;
</script>
<p style="color: {color}">
Yes this will work
</p>
Upside here is flexibility if you only have one or two styles to adjust, downside is that you won't be able to adjust multiple CSS properties from a single prop.
or
You can still use the :global selector but just add a specific ref to the element being styled in the child like so:
<!-- in parent component -->
<script>
import Nested from './Nested.svelte';
</script>
<Nested ref="green"/>
<style>
:global([ref=green]) {
background: green;
color: white;
padding: 5px;
border-radius: .5rem;
}
</style>
<!-- in Nested.svelte -->
<script>
export let ref;
</script>
<p {ref}>
Yes this will work also
</p>
This ensures global only affects the exact ref element inside the child it's intended for and not any other classes or native elements. You can see it in action at this REPL link
Upvotes: 27