HTML exportparts 全域性屬性
exportparts 全域性屬性允許您透過匯出其 part 名稱來選擇和樣式化巢狀 Shadow Tree 中存在的元素。
Shadow Tree 是一個隔離的結構,其中識別符號、類和樣式無法透過屬於常規 DOM 的選擇器或查詢訪問。有兩個 HTML 屬性可以應用於 Shadow Tree 元素,它們可以從外部定位 Shadow Tree 的 CSS 樣式:part 和 exportparts。
全域性 part 屬性使 Shadow Tree 元素對其父 DOM 可見。part 名稱用作 ::part() 偽元素的引數。透過這種方式,您可以從 Shadow Tree 外部將其 CSS 樣式應用於 Shadow Tree 中的元素。但是,::part() 偽元素僅對父 DOM 可見。這意味著,當 Shadow Tree 巢狀時,這些部分對於直接父級以外的任何祖先都是不可見的。exportparts 屬性解決了此限制。
exportparts 屬性使 Shadow Tree 的部分在 Shadow DOM 外部可見。這個概念被稱為“匯出”。exportparts 屬性放置在元素的shadow host上,即 Shadow Tree 所附加的元素。此屬性的值是 Shadow Tree 中存在的 part 名稱的逗號分隔列表。這些名稱可供當前結構外部的 DOM 使用。
<template id="ancestor-component">
<nested-component exportparts="part1, part2, part5"></nested-component>
</template>
匯出 part 時,您可以選擇為該部分分配不同的名稱,如下面的程式碼片段所示。exportparts 屬性的值實際上是 part 名稱對映的逗號分隔列表。因此,上面的程式碼片段中的 exportparts 屬性等同於 exportparts="part1:part1, part2:part2, part5:part5,表示每個 part 都以相同的名稱匯出。在每個對映中,第一個字串指定 Shadow Tree 中部分的名稱,第二個字串指定該部分將在外部暴露的名稱。
<template id="ancestor-component">
<nested-component
exportparts="part1:exposed1, part2:exposed2"></nested-component>
</template>
示例
基本元件
為了演示 exportparts 如何用於啟用對巢狀元件內部分的樣式設定,我們將建立一個元件,然後將其巢狀在另一個元件中。
HTML
首先,讓我們建立一個我們將用另一個元件包裝的卡片元件。我們還使用了我們建立的新元素,並用純文字填充插槽作為內容。
<template id="card-component-template">
<style>
:host {
display: block;
}
</style>
<div class="base" part="base">
<div part="header"><slot name="header_slot"></slot></div>
<div part="body"><slot name="body_slot"></slot></div>
<div part="footer"><slot name="footer_slot"></slot></div>
</div>
</template>
<card-component>
<p slot="header_slot">This is the header</p>
<p slot="body_slot">This is the body</p>
<p slot="footer_slot">This is the footer</p>
</card-component>
JavaScript
我們使用 JavaScript 來定義上面 HTML 中定義的 Web 元件
customElements.define(
"card-component",
class extends HTMLElement {
constructor() {
super(); // Always call super first in constructor
const cardComponent = document.getElementById(
"card-component-template",
).content;
const shadowRoot = this.attachShadow({
mode: "open",
});
shadowRoot.appendChild(cardComponent.cloneNode(true));
}
},
);
CSS
我們使用 ::part 偽元素來樣式化 <card-component> Shadow Tree 的部分
::part(body) {
color: red;
font-style: italic;
}
結果
巢狀元件
在上面的 <card-component> 示例的基礎上,我們透過將 <card-component> 包裝在另一個元件中來建立一個巢狀元件;在這種情況下,是 <card-wrapper> 元件。然後,我們匯出巢狀元件中那些我們希望從元件 Shadow Tree 外部進行樣式設定的部分,使用 exportparts 屬性。
HTML
<template id="card-wrapper">
<style>
:host {
display: block;
}
</style>
<card-component exportparts="base, header, body">
<slot name="H" slot="header_slot"></slot>
<slot name="B" slot="body_slot"></slot>
<slot name="F" slot="footer_slot"></slot>
</card-component>
</template>
我們包含一個 <card-wrapper> 自定義元素,以及一個 <card-component> 用於對比
<h2>Card wrapper</h2>
<card-wrapper>
<p slot="H">This is the header</p>
<p slot="B">This is the body</p>
<p slot="F">This is the footer</p>
</card-wrapper>
<h2>Card component</h2>
<card-component>
<p slot="header_slot">This is the header</p>
<p slot="body_slot">This is the body</p>
<p slot="footer_slot">This is the footer</p>
</card-component>
JavaScript
customElements.define(
"card-wrapper",
class extends HTMLElement {
constructor() {
super(); // Always call super first in constructor
const cardWrapper = document.getElementById("card-wrapper").content;
const shadowRoot = this.attachShadow({
mode: "open",
});
shadowRoot.appendChild(cardWrapper.cloneNode(true));
}
},
);
CSS
現在,我們可以直接定位 <card-component> 的部分,以及當它巢狀在 <card-wrapper> 中時,如下所示
h2 {
background-color: #dedede;
}
card-wrapper,
card-component {
border: 1px dashed blue;
width: fit-content;
}
::part(body) {
color: red;
font-style: italic;
}
::part(header),
::part(footer) {
font-weight: bold;
}
結果
注意:當巢狀時,footer 不是粗體,因為我們沒有將其包含在 exportparts 中。
暴露對映的部分
為了重新命名匯出的部分,我們包含一個逗號分隔的對映部分列表,每個對映部分包含原始名稱和匯出名稱,用冒號 (:) 分隔
HTML
我們使用重對映語法更新之前的 <card-wrapper> 自定義元素(從匯出的部分列表中省略 body)
<template id="card-wrapper">
<card-component
exportparts="
base:card__base,
header:card__header,
footer:card__footer
">
<span slot="header_slot"><slot name="H"></slot></span>
<span slot="body_slot"><slot name="B"></slot></span>
<span slot="footer_slot"><slot name="F"></slot></span>
</card-component>
</template>
JavaScript
customElements.define(
"card-wrapper",
class extends HTMLElement {
constructor() {
super(); // Always call super first in constructor
const cardWrapper = document.getElementById("card-wrapper").content;
const shadowRoot = this.attachShadow({
mode: "open",
});
shadowRoot.appendChild(cardWrapper.cloneNode(true));
}
},
);
CSS
在從 <card-wrapper> 中定位 <card-component> 的部分時,我們只能透過其暴露的部分名稱來樣式化匯出的部分
/* selects the exported parts name */
::part(card__header) {
font-weight: bold;
}
/* selects nothing: these part names were not exported */
::part(footer),
::part(body) {
font-weight: bold;
}
結果
規範
| 規範 |
|---|
| CSS 影子部分 # element-attrdef-html-global-exportparts |
瀏覽器相容性
載入中…
另見
partHTML 屬性<template>和<slot>HTML 元素::part和::slotted偽元素:host偽類ShadowRoot介面Element.part屬性- 使用模板和插槽
- CSS 作用域模組