Spec-Zone.ru › HTML

exportparts

Атрибут exportparts глобальный атрибут позволяет выбирать и стилизовать элементы, существующие во вложенных тенированных деревьях, экспортируя их part имена.

Тенью дерево является изолированной структурой, где идентификаторы, классы и стили недоступны для селекторов или запросов, относящихся к обычному DOM. Есть два HTML-атрибута, которые могут быть применены к элементам тенированного дерева, чтобы разрешить нацеливание на CSS-стили извне тенированного дерева: part и exportparts.

Глобальный атрибут part делает элемент тенированного дерева видимым для родительского DOM. Имя part используется в качестве параметра псевдоэлемента ::part(). Таким образом, вы можете применять CSS-стили к элементам в тенированном дереве извне его. Однако, псевдоэлемент ::part() виден только родительскому DOM. Это означает, что когда тенированное дерево вложено, части не видны ни одному предку, кроме непосредственного родителя. Атрибут exportparts решает эту ограниченность.

Атрибут exportparts позволяет делать части тенированного дерева видимыми за пределами тенированного DOM. Этот концепция называется "экспортом". Атрибут exportparts размещается на элементе-хосте тени, который является элементом, к которому прикреплено тенированное дерево. Значением этого атрибута является список имён part разделённых запятыми, присутствующих в тенированном дереве. Эти имена становятся доступными для DOM вне текущей структуры.

html
<template id="ancestor-component">
  <nested-component exportparts="part1, part2, part5"></nested-component>
</template>

При экспорте part, вы можете назначить разное имя части, как показано в фрагменте ниже. Значение атрибута exportparts фактически является списком сопоставлений имён частей, разделённых запятыми. Таким образом, атрибут exportparts в приведённом выше фрагменте кода эквивалентен exportparts="part1:part1, part2:part2, part5:part5, указывающему, что каждая part экспортируется с тем же именем. В каждом сопоставлении первая строка указывает имя части внутри тенированного дерева, а вторая строка указывает имя, с которым часть будет доступна снаружи.

html
<template id="ancestor-component">
  <nested-component
    exportparts="part1:exposed1, part2:exposed2"></nested-component>
</template>

Примеры

Базовый компонент

Для демонстрации использования exportparts для включения нацеливания на части внутри вложенных компонентов, мы создадим компонент и затем вложим его в другой компонент.

HTML

Сначала создадим компонент карточки, который затем обернём другим компонентом. Мы также используем новый элемент, заполняя слоты текстом в качестве контента.

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 выше:

js
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:

css
::part(body) {
  color: red;
  font-style: italic;
}

Результаты

Вложенный компонент

Продолжая пример <card-component>, мы создаём вложенный компонент, обернув <card-component> другим компонентом; в этом случае компонентом <card-wrapper>. Затем мы экспортируем части из вложенного компонента, которые мы хотим сделать стилизуемыми извне тенированного дерева компонента с помощью атрибута exportparts.

HTML

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> для сравнения:

html
<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

js
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>, как показано ниже:

css
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 из списка экспортированных частей):

html
<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

js
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>, мы можем стилизовать только экспортированные части по их экспонированным именам:

css
/* 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 Shadow Parts
# element-attrdef-html-global-exportparts

Совместимость с браузерами

Рабочие столы Мобильные устройства
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

См. также

  • part HTML-атрибут
  • <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

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API