Skip to main content
Basic Svelte
Introduction
Reactivity
Props
Logic
Events
Bindings
Classes and styles
Actions
Transitions
Advanced Svelte
Advanced reactivity
Reusing content
Motion
Advanced bindings
Advanced transitions
Context API
Special elements
<script module>
Next steps
Basic SvelteKit
Introduction
Routing
Loading data
Headers and cookies
Shared modules
Forms
API routes
$app/state
Errors and redirects
Advanced SvelteKit
Hooks
Page options
Link options
Advanced routing
Advanced loading
Environment variables
Conclusion

Often, you need to influence the styles inside a child component. Perhaps we want to make these boxes red, green and blue.

One way to do this is with the :global CSS modifier, which allows you to indiscriminately target elements inside other components:

App
<style>
	.boxes :global(.box:nth-child(1)) {
		background-color: red;
	}

	.boxes :global(.box:nth-child(2)) {
		background-color: green;
	}

	.boxes :global(.box:nth-child(3)) {
		background-color: blue;
	}
</style>

But there are lots of reasons not to do that. For one thing, it’s extremely verbose. For another, it’s brittle — any changes to the implementation details of Box.svelte could break the selector.

Most of all though, it’s rude. Components should be able to decide for themselves which styles can be controlled from ‘outside’, in the same way they decide which variables are exposed as props. :global should be used as an escape hatch — a last resort.

Inside Box.svelte, change background-color so that it is determined by a CSS custom property:

Box
<style>
	.box {
		width: 5em;
		height: 5em;
		border-radius: 0.5em;
		margin: 0 0 1em 0;
		background-color: var(--color, #ddd);
	}
</style>

Any parent element (such as <div class="boxes">) can set the value of --color, but we can also set it on individual components:

App
<div class="boxes">
	<Box --color="red" />
	<Box --color="green" />
	<Box --color="blue" />
</div>

The values can be dynamic, like any other attribute.

This feature works by wrapping each component in an element with display: contents, where needed, and applying the custom properties to it. If you inspect the elements, you’ll see markup like this:

<svelte-css-wrapper style="display: contents; --color: red;">
	<!-- contents -->
</svelte-css-wrapper>

Because of display: contents this won’t affect your layout, but the extra element can affect selectors like .parent > .child.

Edit this page on GitHub

1
2
3
4
5
6
7
8
9
<script>
	import Box from './Box.svelte';
</script>
 
<div class="boxes">
	<Box />
	<Box />
	<Box />
</div>