跳到主要内容
版本: v8

CSS 阴影部分

CSS 阴影部分允许开发者在阴影树内部对元素的 CSS 属性进行样式设置。这对于自定义 Ionic Framework Shadow DOM 组件非常有用。

为什么使用阴影部分?

Ionic Framework 是一组分布式的 Web 组件。Web 组件遵循 Shadow DOM 规范 以封装样式和标记。

注意

Ionic Framework 组件 **并非全部** 都是 Shadow DOM 组件。如果组件是 Shadow DOM 组件,则在其 组件文档 的右上角会显示一个徽章。Shadow DOM 组件的一个示例是 按钮组件

Shadow DOM 有助于防止样式泄漏到组件之外,并无意中应用于其他元素。例如,我们将 .button 类分配给我们的 ion-button 组件。如果没有 Shadow DOM 封装,如果用户在其自己的元素之一上设置了 .button 类,它将继承 Ionic Framework 按钮样式。由于 ion-button 是一个 Shadow 组件,因此这不是问题。

但是,由于这种封装,样式也无法渗透到 Shadow 组件的内部元素。这意味着如果 Shadow 组件在其阴影树内部呈现元素,则无法使用 CSS 直接定位内部元素。以 ion-select 组件为例,它呈现以下标记

<ion-select>
#shadow-root
<div class="select-text select-placeholder"></div>
<div class="select-icon"></div>
</ion-select>

占位符文本和图标元素位于 #shadow-root 内部,这意味着以下 CSS **不会** 工作以设置占位符的样式

/* Does NOT work */
ion-select .select-placeholder {
color: blue;
}

那么我们如何解决这个问题呢?CSS 阴影部分

阴影部分解释

阴影部分允许开发者在阴影树内部,从阴影树外部对内部进行样式设置。为此,部分必须被公开,然后可以使用 ::part 对其进行样式设置。

公开部分

创建 Shadow DOM 组件时,可以通过在元素上分配 part 属性,将部分添加到阴影树内的元素。这已添加到 Ionic Framework 的组件中,无需最终用户采取任何操作。

继续使用 ion-select 组件为例,标记更新为如下所示

<ion-select>
#shadow-root
<div part="placeholder" class="select-text select-placeholder"></div>
<div part="icon" class="select-icon"></div>
</ion-select>

上面显示了两个部分:placeholdericon。请参阅 选择文档,了解其所有部分。

公开这些部分后,现在可以使用 ::part 直接对元素进行样式设置。

::part 的工作原理

::part() 伪元素允许开发者选择阴影树内部通过部分属性公开的元素。

由于我们知道 ion-select 公开了 placeholder 部分以设置未选择任何值时文本的样式,因此我们可以通过以下方式对其进行自定义

ion-select::part(placeholder) {
color: blue;
opacity: 1;
}

使用 ::part 设置样式允许更改该元素接受的任何 CSS 属性。

除了能够定位部分之外,还可以对 伪元素 进行样式设置,而无需显式公开它们

ion-select::part(placeholder)::first-letter {
font-size: 22px;
font-weight: 500;
}

部分也适用于大多数 伪类

ion-item::part(native):hover {
color: green;
}
注意

供应商前缀的伪元素结构性伪类 有些已知的限制。

Ionic Framework 部分

Ionic Framework 组件的所有公开部分都可以在其 API 页面的 CSS 阴影部分标题下找到。要查看所有组件及其 API 页面,请参阅 组件文档

为了拥有部分,组件必须满足以下条件

  • 这是一个 Shadow DOM 组件。如果它是 作用域 或 Light DOM 组件,则可以直接定位子元素。如果组件是作用域或阴影组件,则会在其 组件文档页面 上列出其名称。
  • 它包含子元素。例如,ion-card-header 是一个 Shadow 组件,但所有样式都应用于宿主元素。由于它没有子元素,因此不需要部分。
  • 子元素不是结构性的。在某些组件(包括 ion-title)中,子元素是用于定位内部元素的结构元素。我们不建议自定义结构元素,因为这会导致意外的结果。
注意

我们欢迎对其他部分的建议。在请求部分时,请使用尽可能多的信息创建一个新的 GitHub 问题

已知限制

浏览器支持

CSS 阴影部分在所有主要浏览器的最新版本中都受支持。但是,一些旧版本不支持阴影部分。在应用程序中实现部分之前,请验证 浏览器支持 是否满足要求。如果需要支持旧版本浏览器,我们建议继续使用 CSS 变量 来设置样式。

供应商前缀的伪元素

供应商前缀

伪元素目前不受支持。这方面的例子就是任何 ::-webkit-scrollbar 伪元素

/* Does NOT work */
my-component::part(scroll)::-webkit-scrollbar {
background: green;
}

有关更多信息,请参阅 GitHub 上的此问题

结构性伪类

大多数伪类都支持部分,但是 结构性伪类 不支持。以下是不起作用的结构性伪类的示例。

/* Does NOT work */
my-component::part(container):first-child {
background: green;
}

/* Does NOT work */
my-component::part(container):last-child {
background: green;
}

链接部分

::part() 伪元素无法匹配其他 ::part()

例如,my-component::part(button)::part(label) 不会匹配任何内容。这是因为这样做会公开比预期更多的结构信息。

如果 <my-component> 的内部按钮使用类似 part="label => button-label" 的东西将按钮的内部部分转发到面板自己的部分元素映射中,那么类似 my-component::part(button-label) 的选择器将只选择一个按钮的标签,忽略任何其他标签。