exportparts
Атрибут exportparts глобальный атрибут позволяет выбирать и стилизовать элементы, существующие во вложенных тенированных деревьях, экспортируя их part имена.
Тенью дерево является изолированной структурой, где идентификаторы, классы и стили недоступны для селекторов или запросов, относящихся к обычному DOM. Есть два HTML-атрибута, которые могут быть применены к элементам тенированного дерева, чтобы разрешить нацеливание на CSS-стили извне тенированного дерева: part и exportparts.
Глобальный атрибут part делает элемент тенированного дерева видимым для родительского DOM. Имя part используется в качестве параметра псевдоэлемента ::part(). Таким образом, вы можете применять CSS-стили к элементам в тенированном дереве извне его. Однако, псевдоэлемент ::part() виден только родительскому DOM. Это означает, что когда тенированное дерево вложено, части не видны ни одному предку, кроме непосредственного родителя. Атрибут exportparts решает эту ограниченность.
Атрибут exportparts позволяет делать части тенированного дерева видимыми за пределами тенированного DOM. Этот концепция называется "экспортом". Атрибут exportparts размещается на элементе-хосте тени, который является элементом, к которому прикреплено тенированное дерево. Значением этого атрибута является список имён part разделённых запятыми, присутствующих в тенированном дереве. Эти имена становятся доступными для DOM вне текущей структуры.
<template id="ancestor-component"> <nested-component exportparts="part1, part2, part5"></nested-component> </template>
При экспорте part, вы можете назначить разное имя части, как показано в фрагменте ниже. Значение атрибута exportparts фактически является списком сопоставлений имён частей, разделённых запятыми. Таким образом, атрибут exportparts в приведённом выше фрагменте кода эквивалентен exportparts="part1:part1, part2:part2, part5:part5, указывающему, что каждая part экспортируется с тем же именем. В каждом сопоставлении первая строка указывает имя части внутри тенированного дерева, а вторая строка указывает имя, с которым часть будет доступна снаружи.
<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 выше:
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
Мы стилизуем части тенированного дерева <card-component> с помощью псевдоэлемента ::part:
::part(body) { color: red; font-style: italic; }
Результаты
Вложенный компонент
Продолжая пример <card-component>, мы создаём вложенный компонент, обернув <card-component> другим компонентом; в этом случае компонентом <card-wrapper>. Затем мы экспортируем части из вложенного компонента, которые мы хотим сделать стилизуемыми извне тенированного дерева компонента с помощью атрибута 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-component> изнутри <card-wrapper>, мы можем стилизовать только экспортированные части по их экспонированным именам:
/* 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; }
Результаты
Спецификации
Совместимость с браузерами
| Рабочие столы | Мобильные устройства | ||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|
| Chrome | Edge | Firefox | Opera | Safari | Chrome Android | Firefox for Android | Opera Android | Safari на IOS | Samsung Internet | WebView Android | |
exportparts |
73 | 79 | 72 | 60 | 13.1 | 73 | 79 | 52 | 13.4 | 11.0 | 73 |
См. также
-
partHTML-атрибут -
<template>и<slot>HTML-элементы -
::partи::slottedпсевдоэлементы -
:hostпсевдокласс -
ShadowRootинтерфейс -
Element.partсвойство - Использование шаблонов и слотов
- Модуль CSS-ограничения
© 2005–2023 MDN contributors.
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.
https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes/exportparts