::part() 是组件作者显式暴露的样式接口,需在 Shadow DOM 内节点添加静态 part 属性(如 <span part="label">),外部 CSS 才能通过 ::part(label) 定制样式;不支持动态值、slot 内容或继承,且 Firefox 至今未实现。

::part() 不是穿透工具,是组件作者主动开的“样式小窗”——没标记 part 属性,外部写再多 my-button::part(icon) 都等于对空气喊话。
必须由组件内部显式添加 part 属性才能生效
外部 CSS 写 my-input::part(label) 无效?先检查组件 shadow tree 里有没有节点带 part="label"。没有就加,不能靠猜测或继承补救。
-
part必须写在 shadow root 内部的真实 DOM 节点上,比如<span part="label">用户名</span> - 不能写在
<slot>上,也不能写在 slot 分发进来的外部内容上(那是::slotted()的事) - 同一个节点可声明多个 part,用空格分隔:
part="label required error",外部可用::part(required)单独选中 - 不支持动态生成 part 值(如
part={this.state.type}),必须是静态字符串属性
::part() 在不同浏览器里的兼容性现实
Chrome/Edge 97+ 原生支持,但 Safari 和 Firefox 仍不可靠——尤其企业内网用户大概率卡在旧版 macOS + Safari 15.3 或更早。
将调研报告、方案对比、数据分析、需求梳理、会议纪要、设计说明、代码评审、学习笔记等任务产物输出为可在浏览器直接打开的单文件 HTML,替代 Markdown 作为最终交付物。Markdown 在信息密度、视觉清晰度和可分享性上已跟不上 AI 产物的丰富度,HTML 能同时承载排版、表格、SVG 等。
- Safari 自 15.4 起支持,但需手动开启
about:config中的Experimental Web Platform Features - Firefox 截至 2026 年 5 月仍未实现
::part(),@supports selector(::part(foo))永远返回 false - 别依赖 CanIUse 的“支持”标记就上线;真机测 iOS 16.7 + Safari、macOS 12.6 + Safari 是底线
- 渐进增强建议:用
@supports selector(::part(foo))包裹关键样式,fallback 到 CSS 自定义属性(如--my-input-label-color)
为什么 !important、全局 class、<style> 放 <head> 全部失效
Shadow DOM 的样式隔离是硬边界,不是优先级问题。外部选择器根本进不去 shadow tree,!important 连参与层叠的机会都没有。
立即学习“前端免费学习笔记(深入)”;
-
my-input div { color: red !important; }—— 完全不匹配,连计算都不触发 - 给宿主元素加 class:
<my-input class="theme-dark">,然后外部写.theme-dark ::part(label) { color: white; }?不行,class 在 host 上,::part()只认内部part属性 -
<style>标签无论放<head>还是组件外任意位置,对 shadow tree 内部零影响 - 唯一能绕过隔离的三种方式:
:host、::part()、CSS 自定义属性——没有第四个
真正容易被忽略的是:组件一旦交付给第三方使用,part 名称就是公开 API。改名=破壊性变更,必须同步文档、版本号和迁移指南;而很多人只在本地 demo 里试通了就以为万事大吉。


















