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

Shadow DOM дает нам инкапсуляцию стилей с ограниченной областью видимости и средство впускать столько (или меньше) внешнего мира, сколько мы выберем.

Но что, если я хочу сделать свой компонент настраиваемым для некоторых свойств стиля?

В этой статье рассказывается об основах использования настраиваемых свойств CSS для проникновения в теневой DOM и возможности настраивать ваш веб-компонент.

Создание элемента HTML

Мы создадим наш собственный HTML-элемент, используя класс JavaScript, расширяющий базовый HTMLElement. Затем мы вызовем customElements.define() с именем тега, который хотим создать, и только что созданным классом.

В этом примере мы создадим простую карточку с материальным дизайном. Это будет показано, когда мы добавим этот элемент в HTML: <app-card></app-card>

Сначала мы создаем корень Shadow DOM, а затем назначаем строку HTML и CSS корню Shadow DOM innerHTML, как показано ниже.

Попытка отмены

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

// access the div 
app-card > div {
  background-color: #2196F3;
}
// override card class
app-card > .card {
  background-color: #2196F3;
}

Использование настраиваемых свойств CSS

Чтобы решить эту проблему, мы можем использовать Настраиваемые свойства CSS (переменные CSS). Пользовательское свойство CSS, определенное в вашем CSS, может использоваться для изменения некоторых свойств CSS в вашем пользовательском элементе.

Следуя нашему примеру, мы будем использовать переменную card-bg в свойстве background-color, чтобы получить цвет, определяемый тем, кто использует пользовательский элемент.

Теперь мы воспользуемся настраиваемым элементом app-card и создадим переменную card-bg в CSS элемента Body. Мы присвоим переменной шестнадцатеричный цвет #2196F3.

Заключение

Используя эту стратегию, мы можем иметь инкапсулированный элемент CSS в вашем документе, и в то же время мы можем позволить настраивать некоторые свойства с помощью CSS. Вы можете просмотреть полный пример здесь.