Стили¶
Шаблон вашего компонента отображается на его теневой корень. Стили, которые вы добавляете в компонент, автоматически скопируются в корень тени и влияют только на элементы в корне тени компонента.
Shadow DOM обеспечивает надежную инкапсуляцию стилей. Если бы Lit не использовал Shadow DOM, вам пришлось бы быть очень осторожным, чтобы случайно не стилизовать элементы вне вашего компонента, либо предков, либо дочерние элементы компонента. Это может привести к написанию длинных и громоздких имен классов. Используя Shadow DOM, Lit гарантирует, что любой написанный вами селектор будет применяться только к элементам в корневой тени вашего компонента Lit.
Добавление стилей в компонент¶
Вы определяете стили в статическом поле класса styles
, используя тегированную шаблонную литеральную функцию css
. Такое определение стилей обеспечивает наиболее оптимальную производительность:
Стили, которые вы добавляете в свой компонент, скопируются с помощью shadow DOM. Для краткого обзора смотрите Shadow DOM.
Значением статического поля класса styles
может быть:
-
Один тегированный шаблонный литерал.
1
static styles = css`...`;
-
Массив помеченных литералов шаблона.
1
static styles = [ css`...`, css`...`];
Статическое поле класса styles
— это почти всегда лучший способ добавить стили в компонент, но есть некоторые случаи, с которыми нельзя справиться таким образом — например, настройка стилей для каждого экземпляра. Об альтернативных способах добавления стилей см. в разделе Определение масштабируемых стилей в шаблоне.
Использование выражений в статических стилях¶
Статические стили применяются ко всем экземплярам компонента. Любые выражения в CSS оцениваются один раз, а затем повторно используются для всех экземпляров.
Для настройки стилей на основе дерева или для каждого экземпляра используйте пользовательские свойства CSS, чтобы позволить элементам быть тематическими.
Чтобы предотвратить оценку потенциально вредоносного кода компонентами Lit, тег css
позволяет использовать только вложенные выражения, которые сами являются строками или числами с тегом css
.
1 2 3 4 5 |
|
Это ограничение существует для защиты приложений от уязвимостей в безопасности, когда вредоносные стили или даже вредоносный код могут быть внедрены из ненадежных источников, таких как параметры URL или значения базы данных.
Если вам необходимо использовать выражение в литерале css
, который сам не является литералом css
, и вы уверены, что выражение получено из полностью доверенного источника, такого как константа, определенная в вашем собственном коде, то вы можете обернуть выражение функцией unsafeCSS
:
1 2 3 4 5 |
|
Используйте тег unsafeCSS
только с доверенным вводом
Внедрение несанированного CSS представляет собой риск для безопасности. Например, вредоносный CSS может "позвонить домой", добавив URL-адрес изображения, который указывает на сторонний сервер.
Наследование стилей от суперкласса¶
Используя массив тегированных литералов шаблонов, компонент может наследовать стили от суперкласса и добавлять свои собственные стили:
Вы также можете использовать super.styles
для ссылки на свойство styles
суперкласса в JavaScript. Если вы используете TypeScript, мы рекомендуем избегать super.styles
, поскольку компилятор не всегда корректно преобразует его. Явная ссылка на суперкласс, как показано в примере, позволяет избежать этой проблемы.
При написании компонентов, предназначенных для подклассификации на TypeScript, поле static styles
должно быть явно типизировано как CSSResultGroup
, чтобы пользователи могли гибко переопределять styles
с помощью массива:
1 2 3 |
|
Совместное использование стилей¶
Вы можете обмениваться стилями между компонентами, создав модуль, экспортирующий помеченные стили:
1 2 3 4 5 6 7 8 9 |
|
Затем ваш элемент может импортировать стили и добавить их в свое статическое поле класса styles
:
1 2 3 4 5 6 7 8 9 10 11 12 13 |
|
Использование эскейпов юникода в стилях¶
Юникодная последовательность CSS — это обратный слеш, за которым следуют четыре или шесть шестнадцатеричных цифр: например, \2022
для символа пули. Это похоже на формат устаревших экранирующих последовательностей JavaScript octal, поэтому использование таких последовательностей в литерале шаблона с тегом css
приводит к ошибке.
Есть два способа добавить в стили юникод:
- Добавить второй обратный слеш (например,
\\2022
). - Использовать escape-последовательность JavaScript, начинающуюся с
\u
(например,\u2022
).
1 2 3 4 |
|
Обзор стилей теневого DOM¶
В этом разделе приводится краткий обзор теневых стилей DOM.
Стили, которые вы добавляете к компоненту, могут влиять на:
- Теневое дерево (шаблон рендеринга вашего компонента).
- Сам компонент.
- Дочерние элементы компонента.
Стилизация теневого дерева¶
Lit-шаблоны по умолчанию выводятся в теневое дерево. Стили, применяемые к теневому дереву элемента, не влияют на основной документ и другие теневые деревья. Аналогично, за исключением наследуемых CSS-свойств, стили уровня документа не влияют на содержимое теневого дерева.
Когда вы используете стандартные селекторы CSS, они соответствуют только элементам в теневом дереве вашего компонента. Это означает, что вы часто можете использовать очень простые селекторы, поскольку вам не нужно беспокоиться о том, что они случайно стилизуют другие части страницы; например: input
, *
или #my-element
.
Стилизация самого компонента¶
Вы можете стилизовать сам компонент с помощью специальных селекторов :host
. (Элемент, который является владельцем или "хозяином" теневого дерева, называется хост-элементом).
Чтобы создать стили по умолчанию для элемента host, используйте CSS-псевдокласс :host
и функцию CSS-псевдокласса :host()
.
:host
выбирает элемент-хост.:host(selector)
выбирает принимающий элемент, но только если принимающий элемент соответствует selector.
Обратите внимание, что на элемент host могут влиять стили, находящиеся вне дерева теней, поэтому стили, заданные в правилах :host
и :host()
, следует рассматривать как стили по умолчанию, которые могут быть переопределены пользователем. Например:
1 2 3 |
|
Стилизация дочерних компонентов¶
Ваш компонент может принимать дочерние элементы (например, элемент <ul>
может иметь дочерние элементы <li>
). Чтобы отобразить дочерние элементы, ваш шаблон должен включать один или несколько элементов <slot>
, как описано в Render children with the slot element.
Элемент <slot>
выступает в качестве заполнителя в теневом дереве, где отображаются дочерние элементы основного элемента.
Используйте CSS-псевдоэлемент ::slotted()
для выбора дочерних элементов, которые включены в ваш шаблон через <slot>
.
::slotted(*)
соответствует всем элементам с прорезью.::slotted(p)
соответствует абзацам с прорезью.p ::slotted(*)
соответствует элементам со слотами, где<slot>
является потомком элемента абзаца.
Обратите внимание, что только прямые дочерние элементы слота могут быть стилизованы с помощью ::slotted()
.
1 2 3 4 5 6 7 |
|
Кроме того, дочерние элементы могут быть стилизованы вне дерева теней, поэтому следует рассматривать стили ::slotted()
как стили по умолчанию, которые могут быть переопределены.
1 2 3 |
|
Ограничения в полифилле ShadyCSS вокруг содержимого слотов
Смотрите Ограничения ShadyCSS для получения подробной информации о том, как использовать синтаксис ::slotted()
в удобном для полифилла виде.
Определение масштабируемых стилей в шаблоне¶
Мы рекомендуем использовать статическое поле класса styles
для оптимальной производительности. Однако иногда вам может понадобиться определить стили в шаблоне Lit. Существует два способа добавления стилей в шаблон:
- Добавить стили с помощью элемента
<style>
. - Добавить стили с помощью внешней таблицы стилей (не рекомендуется).
Каждый из этих методов имеет свой набор преимуществ и недостатков.
В элементе стиля¶
Обычно стили помещаются в статическое поле класса styles
; однако статические стили
элемента оцениваются один раз для каждого класса. Иногда может потребоваться настройка стилей для каждого элемента. Для этого мы рекомендуем использовать свойства CSS для создания тематических элементов. Также вы можете включить элементы <style>
в шаблон Lit. Они обновляются для каждого экземпляра.
1 2 3 4 5 6 7 8 |
|
Ограничения полифилла ShadyCSS в отношении стилизации по экземплярам
Стилизация по экземплярам не поддерживается полифиллом ShadyCSS. Подробности см. в разделе Ограничения ShadyCSS.
Выражения и элементы стиля¶
Использование выражений внутри элементов стиля имеет ряд важных ограничений и проблем с производительностью.
1 2 3 4 5 6 7 8 9 10 11 |
|
Ограничения в полифилле ShadyCSS для выражений
Выражения в элементах <style>
не будут обновляться для каждого экземпляра в ShadyCSS, что связано с ограничениями полифилла ShadyCSS. Кроме того, узлы <style>
не могут быть переданы в качестве значений выражений при использовании полифилла ShadyCSS. Дополнительную информацию см. в разделе Ограничения ShadyCSS.
Оценка выражения внутри элемента <style>
крайне неэффективна. При изменении любого текста внутри элемента <style>
браузеру приходится заново анализировать весь элемент <style>
, что приводит к ненужной работе.
Чтобы снизить эти затраты, отделите стили, требующие оценки для каждого экземпляра, от тех, которые этого не делают.
1 2 3 4 5 6 |
|
Импорт внешней таблицы стилей (не рекомендуется)¶
Хотя вы можете включить внешнюю таблицу стилей в свой шаблон с помощью <link>
, мы не рекомендуем использовать этот подход. Вместо этого стили следует помещать в статическое поле класса styles
.
Предупреждения о внешних таблицах стилей
- Полифилл ShadyCSS не поддерживает внешние таблицы стилей.
- Внешние стили могут вызвать вспышку нестилизованного содержимого (FOUC) во время их загрузки.
- URL в атрибуте
href
является относительным к главному документу. Это нормально, если вы создаете приложение и URL-адреса ваших активов хорошо известны, но избегайте использования внешних таблиц стилей при создании многократно используемого элемента.
Динамические классы и стили¶
Один из способов сделать стили динамическими — добавить выражения к атрибутам class
или style
в вашем шаблоне.
Lit предлагает две директивы, classMap
и styleMap
, для удобного применения классов и стилей в HTML-шаблонах.
Более подробную информацию об этих и других директивах можно найти в документации по встроенным директивам.
Чтобы использовать styleMap
и/или classMap
:
-
Импортируйте
classMap
и/илиstyleMap
:1 2
import { classMap } from 'lit/directives/class-map.js'; import { styleMap } from 'lit/directives/style-map.js';
-
Используйте
classMap
и/илиstyleMap
в шаблоне элемента:
Дополнительную информацию см. в classMap и styleMap.
Темизация¶
Используя CSS-наследование и CSS-переменные и пользовательские свойства вместе, можно легко создавать тематические элементы. Применяя селекторы css для настройки пользовательских свойств CSS, можно легко применять тематизацию на основе деревьев и отдельных экземпляров. Вот пример:
Наследование CSS¶
Наследование CSS позволяет родительским и основным элементам передавать определенные CSS-свойства своим потомкам.
Не все свойства CSS наследуются. К наследуемым свойствам CSS относятся:
color
font-family
и другие свойстваfont-*
.- Все пользовательские свойства CSS (
--*
)
Дополнительную информацию см. в CSS Inheritance on MDN.
Вы можете использовать наследование CSS для установки стилей элемента-предка, которые наследуются его потомками:
1 2 3 4 5 6 |
|
Пользовательские свойства CSS¶
Наследует все пользовательские свойства CSS (--custom-property-name
). Вы можете использовать это, чтобы сделать стили вашего компонента настраиваемыми извне.
В следующем компоненте цвет фона задается переменной CSS. CSS-переменная использует значение --my-background
, если оно было задано селектором, соответствующим предку в дереве DOM, а в противном случае по умолчанию принимает значение yellow
:
1 2 3 4 5 6 7 8 9 10 |
|
Пользователи этого компонента могут установить значение --my-background
, используя тег my-element
в качестве CSS-селектора:
1 2 3 4 5 6 |
|
--my-background
настраивается для каждого экземпляра my-element
:
1 2 3 4 5 6 7 8 9 10 |
|
Дополнительную информацию см. в CSS Custom Properties on MDN.