样式

您的组件模板渲染到其 Shadow DOM 根节点。您添加到组件的样式将自动 _作用域_ 到 Shadow DOM 根节点,并且仅影响组件的 Shadow DOM 根节点中的元素。

Shadow DOM 为样式提供了强大的封装。如果 Lit 不使用 Shadow DOM,您将需要非常小心,不要意外地对组件外部的元素(无论是组件的祖先还是子元素)进行样式化。这可能涉及编写冗长且难以使用的类名。通过使用 Shadow DOM,Lit 确保您编写的任何选择器仅应用于 Lit 组件的 Shadow DOM 根节点中的元素。

您使用带标签的模板字面量 css 函数,在静态 styles 类字段中定义作用域样式。以这种方式定义样式将带来最佳性能。

您添加到组件的样式使用 Shadow DOM 进行 _作用域_。有关快速概述,请参阅 Shadow DOM

静态 styles 类字段的值可以是

  • 单个带标签的模板字面量。

  • 带标签的模板字面量数组。

静态 styles 类字段 _几乎总是_ 添加组件样式的最佳方式,但有一些用例无法以这种方式处理——例如,按实例自定义样式。有关添加样式的替代方法,请参阅 在模板中定义作用域样式

静态样式适用于组件的所有实例。CSS 中的任何表达式都会 _一次_ 评估,然后在所有实例中重复使用。

对于基于树或按实例的样式定制,使用 CSS 自定义属性来允许对元素进行 主题化

为了防止 Lit 组件评估可能存在恶意代码,css 标签仅允许嵌套表达式,而这些表达式本身是 css 带标签的字符串或数字。

这种限制的存在是为了保护应用程序免受安全漏洞,这些安全漏洞允许从 URL 参数或数据库值等不可信来源注入恶意样式甚至恶意代码。

如果您必须在 css 字面量中使用不是 css 字面量的表达式,_并且_ 您确信该表达式来自完全可信的来源(例如您自己代码中定义的常量),那么您可以使用 unsafeCSS 函数包装该表达式。

_仅对可信输入使用 unsafeCSS 标签。_ 注入未经消毒的 CSS 是一种安全风险。例如,恶意 CSS 可以通过添加指向第三方服务器的图像 URL 来“呼叫主页”。

使用带标签的模板字面量数组,组件可以继承超类的样式并添加自己的样式。

您还可以使用 super.styles 来引用超类的 styles 属性。如果您使用的是 TypeScript,我们建议避免使用 super.styles,因为编译器并不总是能够正确地将其转换。显式引用超类,如示例中所示,可以避免此问题。

在编写旨在用 TypeScript 子类化的组件时,static styles 字段应该明确地类型化为 CSSResultGroup,以允许用户使用数组覆盖 styles

您可以通过创建一个导出带标签样式的模块来在组件之间共享样式。

然后,您的元素可以导入样式并将它们添加到其静态 styles 类字段中。

CSS 的 Unicode 转义序列是一个反斜杠后跟四个或六个十六进制数字:例如,\2022 代表一个项目符号字符。这类似于 JavaScript 已弃用的 _八进制_ 转义序列的格式,因此在 css 带标签的模板字面量中使用这些序列会导致错误。

有两种解决方法可以将 Unicode 转义序列添加到您的样式中。

  • 添加第二个反斜杠(例如,\\2022)。
  • 使用 JavaScript 转义序列,以 \u 开头(例如,\u2022)。

本节简要概述了 Shadow DOM 样式。

您添加到组件的样式可以影响

默认情况下,Lit 模板渲染到 Shadow DOM 树中。作用域到元素的 Shadow DOM 树的样式不会影响主文档或其他 Shadow DOM 树。同样,除了 继承的 CSS 属性 外,文档级样式不会影响 Shadow DOM 树的内容。

当您使用标准 CSS 选择器时,它们只会匹配您组件的 Shadow DOM 树中的元素。这意味着您通常可以使用非常简单的选择器,因为您不必担心它们会意外地对页面的其他部分进行样式化;例如:input*#my-element

您可以使用特殊的 :host 选择器来样式化组件本身。(拥有或“托管” Shadow DOM 树的元素称为 _宿主元素_。)

要为宿主元素创建默认样式,请使用 :host CSS 伪类和 :host() CSS 伪类函数。

  • :host 选择宿主元素。
  • :host(selector) 选择宿主元素,但前提是宿主元素与 selector 匹配。

请注意,宿主元素可能会受到来自 Shadow DOM 树外部的样式的影响,因此您应该将 :host:host() 规则中设置的样式视为可以被用户覆盖的 _默认样式_。例如

您的组件可能接受子元素(例如,<ul> 元素可以具有 <li> 子元素)。要渲染子元素,您的模板需要包含一个或多个 <slot> 元素,如 使用 slot 元素渲染子元素 中所述。

<slot> 元素充当 Shadow DOM 树中的占位符,在该占位符中显示宿主元素的子元素。

使用 ::slotted() CSS 伪元素选择通过 <slot> 包含在模板中的子元素。

  • ::slotted(*) 匹配所有已插入的元素。
  • ::slotted(p) 匹配已插入的段落。
  • p ::slotted(*) 匹配已插入的元素,其中 <slot> 是段落元素的后代。

请注意,_只有直接插入的子元素_ 可以使用 ::slotted() 进行样式化。

此外,子元素可以从 Shadow DOM 树外部进行样式化,因此您应该将 ::slotted() 样式视为可以被覆盖的默认样式。

_ShadyCSS polyfill 周围已插入内容的限制。_ 有关如何在 polyfill 友好的方式中使用 ::slotted() 语法,请参阅 ShadyCSS 限制

我们建议使用 静态 styles 类字段 来获得最佳性能。但是,有时您可能希望在 Lit 模板中定义样式。有两种方法可以在模板中添加作用域样式。

每种技术都有其自身的优缺点。

通常,样式放置在 静态 styles 类字段 中;但是,元素的静态 styles _每个类_ 评估一次。有时,您可能需要 _按实例_ 自定义样式。为此,我们建议使用 CSS 属性来创建 可主题化元素。或者,您也可以在 Lit 模板中包含 <style> 元素。这些元素将按实例进行更新。

ShadyCSS polyfill 中有关实例样式的限制。 使用 ShadyCSS polyfill 不支持实例样式。有关详细信息,请参阅 ShadyCSS 限制

在样式元素内使用表达式存在一些重要的限制和性能问题。

ShadyCSS polyfill 中有关表达式的限制。 由于 ShadyCSS polyfill 的限制,<style> 元素中的表达式不会在 ShadyCSS 中按实例更新。此外,在使用 ShadyCSS polyfill 时,<style> 节点可能不会作为表达式值传递。有关更多信息,请参阅 ShadyCSS 限制

<style> 元素内评估表达式效率极低。当 <style> 元素内的任何文本发生更改时,浏览器必须重新解析整个 <style> 元素,从而导致不必要的操作。

为了减轻这种成本,请将需要按实例评估的样式与不需要按实例评估的样式分开。

虽然您可以在模板中使用 <link> 包含外部样式表,但我们不建议使用这种方法。相反,样式应该放置在 静态 styles 类字段 中。

外部样式表的注意事项。

  • ShadyCSS polyfill 不支持外部样式表。
  • 外部样式会导致在加载时出现未样式内容闪烁 (FOUC)。
  • href 属性中的 URL 相对于主文档。如果您正在构建应用程序并且您的资产 URL 是众所周知的,则这没关系,但在构建可重用元素时,请避免使用外部样式表。

使样式动态化的一种方法是在模板中向 classstyle 属性添加表达式。

Lit 提供了两个指令 classMapstyleMap,以便在 HTML 模板中方便地应用类和样式。

有关这些指令和其他指令的更多信息,请参阅有关 内置指令 的文档。

要使用 styleMap 和/或 classMap

  1. 导入 classMap 和/或 styleMap

  2. 在元素模板中使用 classMap 和/或 styleMap

有关更多信息,请参阅 classMapstyleMap

通过结合使用 CSS 继承CSS 变量和自定义属性,可以轻松创建可主题化的元素。通过将 css 选择器应用于自定义 CSS 属性,基于树和按实例的主题应用起来非常简单。以下是一个示例

CSS 继承允许父元素和宿主元素将其某些 CSS 属性传播到其后代。

并非所有 CSS 属性都继承。继承的 CSS 属性包括

  • 颜色
  • font-family 和其他 font-* 属性
  • 所有 CSS 自定义属性 (--*)

有关更多信息,请参阅 MDN 上的 CSS 继承

您可以使用 CSS 继承在祖先元素上设置样式,这些样式将被其后代继承

所有 CSS 自定义属性 (--custom-property-name) 都继承。您可以使用此功能使组件的样式可从外部配置。

以下组件将其背景颜色设置为 CSS 变量。如果 --my-background 已由匹配 DOM 树中祖先的选择器设置,则 CSS 变量将使用 --my-background 的值,否则将默认为 yellow

此组件的用户可以使用 my-element 标签作为 CSS 选择器来设置 --my-background 的值

--my-background 可按 my-element 的实例进行配置

有关更多信息,请参阅 MDN 上的 CSS 自定义属性