C

CSS 阴影部分即将到来!

2025-06-10

CSS 阴影部分即将到来!

Firefox 72 发布了一些新的 API,其中两个对 Web Components 用户来说是个好消息。第一个是FormDataEvent基于事件的表单参与,之前仅在 Chromium 中可用。但今天我想重点介绍另一个自 Firefox 69 以来就已实现的功能:partHTML 属性和::part伪元素。

对于创建可自定义组件和设计系统的开发者来说, CSS Shadow Parts提案是最受期待的标准新增功能之一。它是一个全新的 API,用于从外部设置 Shadow DOM 中单个元素的样式。这使得特定 UI 小部件的单个实例能够略微改变外观——这是我们在实际应用中经常需要的功能。

与 CSS 自定义属性(例如 )不同,--primary-color新的::part伪元素赋予了我们梦寐以求的真正灵活性。在 Vaadin,我们早在 2017 年就采用了 CSS 阴影部分的概念,正如这篇关于主题的演讲中所解释的那样。现在,我们很高兴看到它::part终于获得了跨浏览器支持。

历史

自定义伪元素(也称为 CSS Shadow Parts)的概念至少从 2015 年就开始讨论,但最终在 2017 年初达成一致,决定放弃CSS mixins 和@apply提案(该提案从未在 Chrome 中发布),并改为实现::part。三年后——对于 Web 标准来说并不算太久——我们将在 2020 年实现这一目标。

对于那些还记得Monica Dinculescu 的精彩解释的人来说,需要注意的是:规范从那时起已经发生了变化。现在 Fergal Daly 发布了更新版本。另外,今天我主要讨论的是::part,因为::theme,原始提案中的另一个伪元素 ,已经被推迟了。关于 的讨论正在进行中::theme,其未来前景尚不明朗。

但其现状::part看起来非常乐观。Chrome 从 73 版开始支持它现在 Firefox 72 也支持它。Safari 已在技术预览版 94中实现了 CSS 阴影部分,目前仍在等待稳定版本的发布——与基于 Chromium 的 Edge 一样。所以现在是时候尝试::part并学习如何在实践中使用它了。

用法

基本示例

根据规范编辑之一 Tab Atkins 的评论::part,其目的是隐藏 Web 组件的内部细节,而仅公开组件作者明确想要公开的部分。

让我们直接来看示例。下面嵌入的 CodePen 提供了一个<vaadin-details>使用 为自定义元素添加样式的示例::part。这是一个简单的组件,它使用属性暴露了一些元素part

看起来就像经典的原生 CSS,不是吗?即使你在不支持 ::part的浏览器中打开这个演示,也不会出现任何问题:组件仍然会保持其开箱即用的样式,并保持完整的功能。

在像这样的简单情况下使用 CSS Shadow Parts 非常省事。实际上,您只需part在想要暴露的元素上添加 HTML 属性即可。这样,组件使用者就可以自行选择是否使用此 API。

::part与伪元素一起使用

你可能注意到了,上面的示例演示了如何使用 CSS 选择器来设置详情切换按钮的样式::part(toggle)::after。我们也可以::part将此方法与任何其他伪元素结合使用。

如上面的 CodePen 所示,所有支持该功能的浏览器::part都已支持此功能。不过,请不要期望它能与诸如 之类的非标准伪元素一起使用::-webkit-scrollbar

::part与伪类一起使用

影子树中的元素经常需要的另一个功能是能够为某些状态添加样式,例如:hover。我们可以使用 来实现它::part——这也是它如何自然地融入我们习惯的 CSS 编写方式:

虽然其他用户操作伪类(如):focus也可以与一起使用,::part规范明确指出不支持结构伪类(例如:first-child等等)。:nth-of-type():empty

路径转发exportparts

在某些情况下,我们可能需要暴露样式的部分位于嵌套组件中,该组件有自己的影子根。默认情况下,这是不可能的::part,因为它不会递归遍历影子树。

不过,现在有exportparts一个专门处理这种情况的属性。当影子树中的元素具有此属性时,其值定义了从该元素“导出”的部分,并且可以使用以下方式设置样式::part

截至目前,此功能仅作为“白名单”使用。曾有提案建议支持使用类似“通配符”的转发功能。然而,该功能目前尚未标准化,因此尚未在浏览器中实现。-*

特征检测

在某些情况下,你可能需要检测浏览器是否支持 CSS Shadow Parts,例如,加载.css具有 fallback 样式的其他代码块或文件。这可以在 JS 中使用以下代码实现:

'part' in HTMLElement.prototype; // true if "part" is supported
Enter fullscreen mode Exit fullscreen mode

没有跨浏览器的方法来检测::part仅使用 CSS 的支持,因为@supports selector()API 目前仅在 Firefox 中可用。

限制

虽然 CSS Shadow Parts 确实为我们带来了很大的灵活性,但它们在设计上仍然存在一些限制。这些限制与某些伪类有关,这些伪类在::part属于它们之后就不再被允许使用。

::slotted()与使用 Shadow DOM 的任何人所熟悉的伪元素相同,::part不允许在复杂的选择器中使用,因此您不能使用它来设置兄弟节点或子节点的样式 - 只能设置其本身的部分。

另一个重要的限制是:之后无法使用类或属性选择器::part——这些被视为实现细节。一种可能的解决方法是使用多部分方法。

:state()类被设计用于配合使用::part,它应该通过允许 CSS 来涵盖一些用例,例如::part(video):state(playing)使用属性公开的自定义元素的样式part

记录

CSS Shadow Parts 可视为Web 组件公开的 CSS APIpart 。这意味着它们应该遵循语义版本控制——因此,删除或重命名任何属性都需要进行主要版本升级。

web -component-analyzer工具支持@csspartJSDoc 注释,可用于记录自定义元素公开的 CSS Shadow Parts,并将其作为实验性 JSON 格式的一部分输出。

借助<api-viewer>元素(我的个人项目),您可以从 JSON 生成 Web 组件 API 文档,包括 CSS 阴影部分。顺便说一下,<api-viewer>它本身也可以使用 进行样式设置::part

CSS 阴影部分 API 文档

了解更多

由于 CSS Shadow Parts 还是一个相对较新的 API,因此目前还没有太多示例。以下是一些可以::part实际使用的地方:

  • Elix是 Jan Miksovsky 开发的一套实现常见 UI 模式的 Web 组件。Elix 推荐使用元素部件样式以及其他自定义元素外观的方法。

  • Chromium Web UI 元素。这些 Web 组件正在更新,将使用 CSS Shadow Parts 替代 CSS Mixins。您可以在Chrome 设置等多个地方看到它们。

  • Firefox UI。正如 Brian Grinstead 在最近的博客文章中提到的那样,使用 Web Components 重新构建 Firefox UI 的过程导致优先考虑 CSS Shadow Parts 支持以及其他相关功能。

  • web-platform-tests 套件。这个项目对于理解某些功能的工作原理非常有用。您可以检查结果,了解 CSS Shadow Parts 在最新浏览器版本中的工作方式。

  • Mozilla 开发者网络 (MDN) 已经提供了两篇关于::part伪元素part全局属性的文章。他们在项目中也有一个专门的示例web-components-examples

最后,如果您想了解仍在讨论的问题,请查看带有相应标签的CSSWG 问题跟踪器。

概括

CSS Shadow Parts 是一个新的 API,它已经可以在一些项目中使用,尤其是在那些可以接受优雅降级方法的情况下。因此,我强烈建议所有使用 Web 组件库、UI 工具包或设计系统的人都去评估part一下exportparts

鏂囩珷鏉ユ簮锛�https://dev.to/webpadawan/css-shadow-parts-are-coming-mi5
PREV
Web Components 之旅:错误的道路、缺失的部分和有希望的路径
NEXT
如何在不收集令牌的情况下使 JWT 令牌失效