Web Components 的样式

Avatar of Chris Coyier
Chris Coyier

DigitalOcean 为您旅程的每个阶段提供云产品。立即开始使用 200 美元的免费额度!

Nolan Lawson 有一个非常方便且 非常易于使用的小型 emoji-picker-element。但是考虑到您可能在自己的应用中使用它,因此它应该是可样式化的,以便可以很好地整合到任何地方。 如何允许这种样式化并不完全明显。

然而,我不清楚的是如何允许用户对其进行样式化。如果他们想要不同的背景颜色怎么办?如果他们想让表情符号更大怎么办?如果他们想为输入字段使用不同的字体怎么办?

Nolan 列出了四种可能性(我将以一种有助于我理解的方式稍微重命名它们)。

  1. CSS 自定义属性:为样式化内容(如 background: var(--background, white);)。自定义属性穿透 Shadow DOM,因此您实际上是在添加样式挂钩。
  2. 预构建变体:您可以向自定义元素添加 class 属性,这很容易在 Shadow DOM 内部的 CSS 中访问,这要归功于伪选择器,例如 :host(.dark) { background: black; }
  3. Shadow 部分:您将属性添加到想要样式化的内容中,例如 <span part="foo">,然后外部的 CSS 可以像 custom-component::part(foo) { } 那样访问。
  4. 用户强制:尽管 Shadow DOM 具有“输入为空/输出为空”的特点,但您始终可以访问 element.shadowRoot 并注入 <style>,因此始终有一种方法可以将样式注入。

可能值得一提的是,您 slot 到位的 DOM 可以 从“外部”CSS 进行样式化

这是一个非常奇怪的问题。我喜欢 Shadow DOM,因为它是在 Web 平台上最接近作用域样式的东西,作用域样式绝对是一个好主意。但我不喜欢任何这些样式解决方案。它们似乎都强迫我考虑我想提供什么样的样式 API 并对其进行文档化,同时又不鼓励组件之间的一致性。

对我而言,DOM 本身就是一个样式 API。我喜欢作用域保护,但如果我想这样做,应该有一种简单的方法可以进入并为内容设置样式。似乎应该有一种非常简单的纯 CSS 方法可以进入内部并仍然使用级联等。也许用连字符分隔的自定义元素名称就足够了?my-custom-elemement li { }。或者也许它更明确,例如 @shadow my-custom-element li { }。我只是认为它应该更简单。 可构造样式表 似乎也不是朝着简化方向迈出的一步。

上次我 思考 Web Components 的样式化时,我只是试图弄清楚它最初是如何工作的,并没有考虑如何向组件的使用者公开样式选项。

这在日常工作中是否真的会出现问题?确实如此。

在该线程中(目前)我没有看到任何特别好的样式方法选项。如果我是 Dave,我会倾向于什么都不做。提供最少的样式,如果人们想为其设置样式,他们可以根据自己的组件副本以任何方式进行设置。或者他们可以“强制”样式,这意味着您可以完全自由。