Shadow DOM представляет собой технологию инкапсуляции DOM и стилей, позволяющую создавать компоненты с изолированной структурой и стилями. В FAST Element использование Shadow DOM является базовой практикой для построения переиспользуемых веб-компонентов, обеспечивая контроль над внутренней разметкой без риска конфликтов с внешними стилями.
В FAST Element каждый компонент, наследующийся от
FASTElement, по умолчанию может использовать Shadow DOM.
Создание компонента с Shadow DOM осуществляется через метод
@customElement и свойство shadowOptions:
import { FASTElement, html, css, customElement } from "@microsoft/fast-element";
const template = html<MyComponent>`
<div class="container">
<span>${x => x.text}</span>
</div>
`;
const styles = css`
.container {
background-color: #f0f0f0;
padding: 10px;
}
span {
color: #333;
}
`;
@customElement({
name: "my-component",
template,
styles,
shadowOptions: { mode: "open" } // Shadow DOM включен
})
class MyComponent extends FASTElement {
text = "Привет, FAST!";
}
Ключевой момент: shadowOptions.mode
принимает значения open или closed.
open позволяет получить доступ к shadowRoot извне через
element.shadowRoot.closed скрывает shadowRoot, что повышает
инкапсуляцию.Shadow DOM в FAST Element обеспечивает локальные стили, которые применяются только к внутренней структуре компонента. Это предотвращает утечку стилей наружу и конфликт с глобальными CSS. Например, можно создавать сложные компоненты с вложенными элементами, не опасаясь, что внешние классы изменят их внешний вид.
const template = html<MyCard>`
<div class="card">
<header>${x => x.title}</header>
<section>${x => x.content}</section>
</div>
`;
const styles = css`
.card {
border: 1px solid #ccc;
border-radius: 8px;
padding: 16px;
background-color: #fff;
}
header {
font-weight: bold;
margin-bottom: 8px;
}
`;
Даже если глобальный CSS определяет стиль
header { color: red; }, внутри компонента
MyCard стиль Shadow DOM будет сохранять локальный цвет.
Shadow DOM в FAST Element поддерживает слоты, что позволяет создавать гибкие шаблоны с местом для контента, передаваемого из внешнего DOM. Слоты обеспечивают контроль над тем, какие элементы будут вставлены внутрь компонента.
const template = html<MyPanel>`
<div class="panel">
<header><slot name="header"></slot></header>
<main><slot></slot></main>
</div>
`;
Использование слотов позволяет разделять структуру компонента и контент, сохраняя при этом полную инкапсуляцию стилей.
<my-panel>
<span slot="header">Заголовок панели</span>
<p>Основной контент панели</p>
</my-panel>
FAST Element позволяет использовать CSS-переменные для изменения стилей компонентов без нарушения инкапсуляции. Переменные определяются глобально, но применяются локально через Shadow DOM:
:host {
--panel-bg: #fafafa;
--panel-color: #222;
}
.panel {
background-color: var(--panel-bg);
color: var(--panel-color);
padding: 12px;
border-radius: 6px;
}
:host используется для стилизации корневого элемента
shadowRoot. Он позволяет управлять внешним видом компонента, не
затрагивая внутренние классы.
Shadow DOM в FAST Element полностью поддерживает кастомные
события. Внутри компонента события могут всплывать и быть
перехвачены извне, но при этом событие можно сделать приватным через
composed: false:
this.dispatchEvent(new CustomEvent("panelOpen", {
bubbles: true,
composed: true, // событие пробивается через shadow DOM
detail: { open: true }
}));
Использование composed: true позволяет событию проходить
через границы Shadow DOM, что необходимо для интеграции компонентов в
сложные приложения.
FAST Element поддерживает динамическое управление Shadow DOM через директивы и условный рендеринг. Это особенно полезно для компонентов с изменяющейся структурой:
const template = html<MyToggle>`
<button @click=${x => x.toggle()}>Переключить</button>
${x => x.isOpen ? html`<div>Содержимое открыто</div>` : html``}
`;
В таком подходе структура DOM внутри shadowRoot обновляется без изменения внешнего DOM, сохраняя преимущества инкапсуляции.
Shadow DOM минимизирует риски конфликтов стилей, но может увеличивать
количество нод в DOM. FAST Element оптимизирует работу через
обновление только изменённых частей шаблона, что
снижает накладные расходы. Использование html и директив
позволяет максимально эффективно управлять рендерингом внутри Shadow
DOM.
shadowOptions.mode: "open" для
компонентов, где нужен доступ к shadowRoot.:host для управления стилями корневого
элемента.composed, чтобы контролировать их
пробивание через Shadow DOM.Shadow DOM в FAST Element сочетает строгую инкапсуляцию и гибкость настройки, что делает его мощным инструментом для создания переиспользуемых и устойчивых веб-компонентов.