exportparts глобальный атрибут HTML
Baseline Широко доступно
Эта функция хорошо зарекомендовала себя и работает на множестве устройств и в разных версиях браузеров. Она доступна во всех браузерах с июля 2020 года.
Глобальный атрибут 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 template = document.getElementById("card-component-template");
const shadowRoot = this.attachShadow({
mode: "open",
});
shadowRoot.appendChild(document.importNode(template.content, 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 template = document.getElementById("card-wrapper");
const shadowRoot = this.attachShadow({
mode: "open",
});
shadowRoot.appendChild(document.importNode(template.content, 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 template = document.getElementById("card-wrapper");
const shadowRoot = this.attachShadow({
mode: "open",
});
shadowRoot.appendChild(document.importNode(template.content, 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 для Android | Opera для Android | Safari на iOS | Samsung Internet | WebView Android | WebView на iOS | |
exportparts |
73 | 79 | 72 | 60 | 13.1 | 73 | 79 | 52 | 13.4 | 11.0 | 73 | 13.4 |
См. также
-
partатрибут HTML -
Элементы HTML
<template>и<slot> -
Псевдоэлементы
::partи::slotted -
Псевдокласс
:host -
Интерфейс
ShadowRoot -
Свойство
Element.part - Использование шаблонов и слотов
- Модуль области видимости CSS
© 2005–2025 MDN contributors.
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.
https://developer.mozilla.org/en-US/docs/Web/HTML/Reference/Global_attributes/exportparts