本文详细讲解如何在 Svelte 中精确控制插槽内容(slotted content)和导出部分(exported parts)的样式,涵盖父组件样式注入、子组件内部作用域限制、fallback 处理以及现代 CSS::part()与::slotted()的兼容性实践策略。
先讲清楚一个容易被忽略的前提:Svelte 的 本质上属于编译时内容投影(content projection),而非 Web Components 那种 Shadow DOM 封装。这意味着,像 ::part() 或 ::slotted() 这类伪元素,在 Svelte 的插槽体系里根本行不通——它们只对启用了 shadowRoot 的自定义元素生效。如果你在 Svelte 组件里写 AppShell::part(content),Vite/Svelte 编译器会直接报错 Expected a valid CSS identifier,原因就是这语法不属于标准 CSS,且 Svelte 默认不会生成 Shadow DOM。

那么,在实际项目中,我们该如何跨组件边界定制样式外观?下面给出几条经过验证的可行策略。
1. 父组件样式优先(推荐 & 最常用)
Svelte 默认启用 CSS 作用域隔离(scoped styles),但父组件中定义的样式可以直接作用于传入插槽的 DOM 节点——因为它们渲染后都处在同一个文档流中:
Hello from slot!
⚠️ 注意:Svelte 的块默认为 scoped(添加唯一 hash 类名),但插槽内容本身不带 scope 属性,因此父组件中定义的.slotted-text会真实匹配到渲染后的元素——这正是 Svelte 插槽设计的核心优势:简单、高效,没有 Shadow DOM 带来的性能开销。
2. 子组件内控制插槽内容样式(::slotted 不适用,改用类名约定)
虽然 Svelte 不支持 ::slotted(div),但我们可以通过显式类名配合子组件 CSS 实现等效效果:
更健壮的方式是约定接口:在文档中说明“请为 header 插槽内容添加 slot-header 类”,然后在子组件中针对性编写样式:
