通常,你需要控制子组件内部的样式。比如我们想要将这些盒子变成红色、绿色和蓝色。
实现这一点的一种方法是使用 :global
CSS 修饰符,它允许你无差别地定位其他组件内的元素:
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>
但是有很多理由不应该这样做。首先,它非常冗长。其次,它很脆弱 —— 对 Box.svelte
实现细节的任何改变都可能破坏选择器。
最重要的是,这样做很粗暴。组件应该能够自己决定哪些样式可以从”外部”控制,就像它们决定哪些变量作为 props 暴露出去一样。:global
应该作为一个后备方案 —— 最后的手段。
在 Box.svelte
中,将 background-color
修改为通过 CSS 自定义属性 来决定:
Box
<style>
.box {
width: 5em;
height: 5em;
border-radius: 0.5em;
margin: 0 0 1em 0;
background-color: var(--color, #ddd);
}
</style>
任何父元素(比如 <div class="boxes">
)都可以设置 --color
的值,我们也可以在单个组件上设置它:
App
<div class="boxes">
<Box --color="red" />
<Box --color="green" />
<Box --color="blue" />
</div>
这些值可以像其他任何属性一样是动态的。
这个特性通过在需要时将每个组件包裹在一个带有
display: contents
的元素中来实现,并将自定义属性应用于它。如果你检查元素,你会看到像这样的标记:<svelte-css-wrapper style="display: contents; --color: red;"> <!-- contents --> </svelte-css-wrapper>
由于
display: contents
的存在,这不会影响你的布局,但是这个额外的元素可能会影响像.parent > .child
这样的选择器。
1
2
3
4
5
6
7
8
9
<script>
import Box from './Box.svelte';
</script>
<div class="boxes">
<Box />
<Box />
<Box />
</div>