Skip to content

Commit 8c6d0fd

Browse files
author
Rich Harris
committed
component styles
1 parent 20bfbe6 commit 8c6d0fd

File tree

5 files changed

+98
-0
lines changed

5 files changed

+98
-0
lines changed
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
---
2+
title: Component styles
3+
---
4+
5+
Often, you need to influence the styles inside a child component. Perhaps we want to make these boxes red, green and blue.
6+
7+
One way to do this is with the `:global` CSS modifier, which allows you to indiscriminately target elements inside other components:
8+
9+
```svelte
10+
/// file: App.svelte
11+
<style>
12+
.boxes :global(.box:nth-child(1)) {
13+
background-color: red;
14+
}
15+
16+
.boxes :global(.box:nth-child(2)) {
17+
background-color: green;
18+
}
19+
20+
.boxes :global(.box:nth-child(3)) {
21+
background-color: blue;
22+
}
23+
</style>
24+
```
25+
26+
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.
27+
28+
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.
29+
30+
Inside `Box.svelte`, change `background-color` so that it is determined by a [CSS custom property](https://developer.mozilla.org/en-US/docs/Web/CSS/--*):
31+
32+
```svelte
33+
/// file: Box.svelte
34+
<style>
35+
.box {
36+
width: 5em;
37+
height: 5em;
38+
border-radius: 0.5em;
39+
margin: 0 0 1em 0;
40+
background: +++var(--color, #ddd)+++;
41+
}
42+
</style>
43+
```
44+
45+
Any parent element (such as `<div class="boxes">`) can set the value of `--color`, but we can also set it on individual components:
46+
47+
```svelte
48+
/// file: App.svelte
49+
<div class="boxes">
50+
<Box +++--color="red"+++ />
51+
<Box +++--color="green"+++ />
52+
<Box +++--color="blue"+++ />
53+
</div>
54+
```
55+
56+
The values can be dynamic, like any other attribute.
57+
58+
This feature works by wrapping each component in a `<div style="display: contents">`, where needed, and applying the custom properties to it.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
<script>
2+
import Box from './Box.svelte';
3+
</script>
4+
5+
<div class="boxes">
6+
<Box />
7+
<Box />
8+
<Box />
9+
</div>
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
<div class="box" />
2+
3+
<style>
4+
.box {
5+
width: 5em;
6+
height: 5em;
7+
border-radius: 0.5em;
8+
margin: 0 0 1em 0;
9+
background: #ddd;
10+
}
11+
</style>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
<script>
2+
import Box from './Box.svelte';
3+
</script>
4+
5+
<div class="boxes">
6+
<Box --color="red" />
7+
<Box --color="green" />
8+
<Box --color="blue" />
9+
</div>
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
<div class="box" />
2+
3+
<style>
4+
.box {
5+
width: 5em;
6+
height: 5em;
7+
border-radius: 0.5em;
8+
margin: 0 0 1em 0;
9+
background: var(--color, #ddd);
10+
}
11+
</style>

0 commit comments

Comments
 (0)