Оформление: веб-компоненты
Справочник по оформлению покрывает полный каталог CSS-переменных. Этот документ описывает, как веб-компонент получает тему через shadow DOM.
Как тема доходит до вашего компонента
Shadow DOM блокирует каскад CSS — таблицы стилей, написанные вне вашего компонента, внутри него не действуют. Однако пользовательские CSS-свойства (переменные) границу shadow DOM пересекают. Это означает:
- Пользовательские свойства наследуются через границу shadow DOM. WippyElement также пробрасывает каждое настроенное имя переменной через свой внутренний корень с принудительной темой, поэтому локально загруженные умолчания
theme-config.cssне могут сбросить настроенные значения. - Стили компонентов PrimeVue, утилиты Tailwind и другие таблицы стилей на основе правил не каскадируются внутрь — их нужно явно загружать через
hostCssKeys.
Уровни настройки
L1 — Глобальный: пользовательские CSS-свойства пересекают границу shadow DOM. WippyElement перечисляет действующие карты переменных global/children/page, включая @light / @dark, и устанавливает универсальный мост наследования до слоя вставляемого пользовательского CSS.
L2 — Ограниченная область: то же, что L1, для пользовательских свойств. CSS на основе таблиц стилей (PrimeVue, Tailwind) не каскадируется — используйте hostCssKeys, чтобы явно загрузить их в shadow root.
L3 — config_overrides на уровне страницы: CSS-переменные, заданные оператором через config_overrides, доходят до хоста веб-компонента и внутреннего корня темы через тот же универсальный мост.
custom_css фасада доходит до shadow root (Web Host 1.0.43+, с возможностью отключения). Правила с селекторами не каскадируются через границу, поэтому среда выполнения вставляет составленный пользовательский CSS global + children.
Мост настроенных переменных не зависит от фронтенд-отключения customCss и остаётся активным. Порядок: платформенные умолчания темы → мост наследования настроенных переменных → вставленный пользовательский CSS.
До Web Host 1.0.43 правила
custom_cssфасада не доходили до shadow root компонента — наследовались только пользовательские свойства. На более старых хостах повторите правило внутри собственных стилей веб-компонента или переведите его в форму токена--p-*.
Получение CSS темы
Вынесение JavaScript во внешние зависимости следует полному зафиксированному import-map.json Web Host, в том числе для @wippy-fe/theme. Доставка CSS устроена иначе: shadow root получает ресурсы темы на основе правил только через hostCssKeys либо через включённый в бандл/встроенный CSS.
hostCssKeys — загрузка CSS во время выполнения
Объявите, какие раздаваемые хостом CSS-ресурсы среда выполнения веб-компонента должна вставить в ваш shadow root. Добавьте их в wippyConfig.hostCssKeys:
static get wippyConfig(): WippyElementConfig<ComponentProps> {
return {
propsSchema: pkg.wippy.props as WippyPropsSchema,
hostCssKeys: ['themeConfigUrl', 'iframeCssUrl'] as const,
inlineCss: stylesText,
}
}
| Ключ | Что загружает | Размер | Когда включать |
|---|---|---|---|
themeConfigUrl |
theme-config.css — полная система CSS-переменных --p-* |
~8 КБ | Когда веб-компонент потребляет семантические токены хоста, тёмный режим или оформленную оболочку. Нейтральный по представлению canvas/SVG/график может обойтись без него. |
primeVueCssUrl |
Весь CSS компонентов PrimeVue (режим unstyled) | ~455 КБ | Только если веб-компонент отрисовывает компоненты PrimeVue (<Button>, <Dialog> и т. д.) внутри своего shadow root. |
markdownCssUrl |
Стили markdown для .data-body |
~5 КБ | Только если веб-компонент отрисовывает markdown-содержимое. |
iframeCssUrl |
Оформление полос прокрутки по теме по умолчанию; имя историческое | ~1 КБ | Обязателен для любого веб-компонента, который может прокручиваться, ради единообразия полос прокрутки. |
preflightCssUrl не входит в объединение HostCssKey. Если вам действительно нужен preflight Tailwind v3 внутри shadow root, вызовите hostCss.preflightCssUrl + loadCss() императивно. На практике это требуется редко.
Рекомендации по размеру бандла
hostCssKeys |
Всего подтягивается CSS |
|---|---|
['themeConfigUrl'] |
~8 КБ |
['themeConfigUrl', 'iframeCssUrl'] |
~9 КБ |
['themeConfigUrl', 'markdownCssUrl', 'iframeCssUrl'] |
~14 КБ |
['themeConfigUrl', 'primeVueCssUrl', 'iframeCssUrl'] |
~464 КБ |
Выбирайте независимо:
- Нейтральный по представлению canvas/SVG/график без стандартных продуктовых элементов управления, семантических токенов хоста и утилитарных классов может обойтись без PrimeVue, ресурса темы и Tailwind.
- Любая кнопка, поле ввода, форма, таблица, диалог, меню, тег, подсказка или элемент обратной связи требует эквивалента из PrimeVue,
PrimeVuePluginиprimeVueCssUrl. - Семантические токены хоста, тёмный режим или оформленная оболочка требуют
themeConfigUrl. - Tailwind нужен, когда исходный код использует утилитарные классы Tailwind.
- Прокручиваемое содержимое требует
iframeCssUrl.
inlineCss — CSS времени сборки
Скомпилируйте свой Tailwind/SCSS во время сборки и вставьте его в shadow root через inlineCss. Используйте импорт Vite ?inline:
import stylesText from './styles.css?inline'
static get wippyConfig() {
return {
hostCssKeys: ['themeConfigUrl'] as const,
inlineCss: stylesText,
}
}
Запасной вариант для локальной разработки
Для локальной разработки без хоста импортируйте theme-config.css прямо в свой styles.css, чтобы получить запасные значения переменных:
/* src/styles.css */
@import "@wippy-fe/theme/theme-config.css";
:host {
color: var(--p-text-color);
background: var(--p-content-background);
}
Это даёт значения --p-* по умолчанию, так что ваш компонент корректно отображается в host-less-режиме. Во время выполнения настоящая тема доставляется через hostCssKeys: ['themeConfigUrl'] и имеет приоритет.
Написание CSS компонента
Запрашивайте themeConfigUrl, потребляйте семантические переменные и не переобъявляйте унаследованные умолчания палитры. Семантические алиасы переключаются в режиме Auto и в принудительных режимах:
:host {
color: var(--p-text-color);
background: var(--p-content-background);
border: 1px solid var(--p-content-border-color);
}
.danger-indicator {
color: var(--p-danger-500);
}
Не используйте var(--p-surface-N) для цветов, зависящих от темы — нумерованная шкала surface не переключается в тёмном режиме. Вместо этого используйте семантические алиасы (--p-text-color, --p-content-background, --p-text-muted-color, --p-content-border-color).
Для производных оттенков: color-mix(in srgb, var(--p-content-background) 85%, var(--p-text-color) 15%).
Защитные запасные значения
Веб-компоненты могут работать в host-less dev-режиме (без родительской страницы), поэтому запасное значение допустимо:
/* Допустимо в веб-компонентах — только как запасной вариант для dev-просмотра */
color: var(--p-text-color, #404040);
Ограничьтесь одним запасным значением на логический цвет, помечайте их как "только для dev-просмотра" и никогда не используйте их в микрофронтенд-приложениях (там переменные всегда предоставляет хост).
Чтение переменных в JS
При передаче значений темы в контексты вне CSS (D3, Canvas, mermaid):
const styles = getComputedStyle(this.$el)
const primaryColor = styles.getPropertyValue('--p-primary-500').trim()
const background = styles.getPropertyValue('--p-content-background').trim()
// передайте в mermaid.init или D3.scaleOrdinal
Типичные шаблоны
// Нейтральный по представлению веб-компонент только с графиком: без элементов управления, токенов хоста, утилит и прокрутки:
hostCssKeys: [] as const
// Веб-компонент, отрисовывающий компоненты PrimeVue внутри Shadow DOM:
hostCssKeys: ['themeConfigUrl', 'primeVueCssUrl', 'iframeCssUrl'] as const
// Веб-компонент, отрисовывающий markdown:
hostCssKeys: ['themeConfigUrl', 'markdownCssUrl', 'iframeCssUrl'] as const
// Пример: веб-компонент mermaid — отрисовывает SVG напрямую, нужны только переменные --p-*:
hostCssKeys: ['themeConfigUrl'] as const
Антипаттерны, специфичные для веб-компонентов
- Зашитые hex-значения внутри
:host { … }— вместо этого используйтеvar(--p-*). - Блоки
<style>с@media (prefers-color-scheme: dark), зашивающие цвета тёмного режима — переменные вtheme-config.cssсами перенастраиваются под тёмную тему; если вы корректно ссылаетесь наvar(--p-*), тёмный режим достаётся бесплатно. - Запрос
primeVueCssUrl, когда веб-компонент не отрисовывает PrimeVue — добавляет большую таблицу стилей без всякой пользы. - Установка
appendTo: 'self'для оверлеев PrimeVue как рутинного решения. УстановитеPrimeVuePluginи оставьте цель по умолчанию; она перенаправляет на закреплённый оверлейный слой во владеющем shadow root. Явныйself— это инлайн-размещение, которое может обрезаться в прокручиваемых оверлеях. - Забытые
bubbles: true, composed: trueпри диспетчеризацииCustomEvent— события не выйдут за пределы shadow DOM. - Решение о вынесении
@wippy-fe/themeво внешние зависимости на основе предположений о CSS вместо полной зафиксированной import map Web Host.
Проверка
Не останавливайтесь на непустом токене. Сравните точное настроенное значение на хосте элемента и во внутреннем корне темы, затем проверьте разрешённый браузером цвет, используемый отрисованным элементом управления:
const el = document.querySelector('your-element')
const inner = el.shadowRoot.querySelector('[data-wippy-theme-root]')
getComputedStyle(el).getPropertyValue('--p-primary-color')
getComputedStyle(inner).getPropertyValue('--p-primary-color')
Повторите для каждого настроенного семейства в режимах Auto-light, Auto-dark, принудительный Light и принудительный Dark. Веб-компонент запрашивает themeConfigUrl и потребляет семантические токены; он не переобъявляет унаследованные умолчания палитры.
Полный порядок отладки: Отладка.
Связанные документы
- theming.md — каталог CSS-переменных и антипаттерны
- micro-frontend-app-theming.md — оформление микрофронтенд-приложений (инъекция в iframe)
- web-component.md — полное руководство по разработке веб-компонентов
- host-less-mode.md — dev-оверлей и host-less-режим
- compliance-checklist.md — полные правила REJECT/WARN для оформления