Правильный способ применения глобальных стилей в Shadow DOM - PullRequest
0 голосов
/ 11 ноября 2018

Эти вопросы похожи на некоторые другие в StackOverflow, но я не смог найти ответа, описывающего мою ситуацию и метод, который не осуждается (и я начинаю думать, что, возможно, не существует какого-либо хорошего решения для этой ситуации) .

Допустим, у нас есть файл main.css, который включает в себя общие стили для кнопок, списков, ссылок и так далее. Так что это просто какой-то стандартный файл .css, который содержит общие стили, которые мы хотим использовать в приложении. И мы хотим применить те же стили к веб-компонентам с Shadow DOM.

Я знаю несколько способов сделать это:

  1. Использование одного из устаревших подходов: :: shadow, >>>, / deep / selectors. Но эти селекторы уже устарели, так что я думаю, что это плохой подход, чтобы двигаться вперед.
  2. Использование переменных CSS. Этот подход хорош для настройки, если нам нужно установить несколько свойств. Но это слишком сложно, если мы хотим перенести 10-20 общих стилей из файла main.css.
  3. Использование оператора @import или тегов "link" внутри Shadow DOM. Это будет работать, но дублирует все стили для каждого компонента. Если у нас будет 10 веб-компонентов, мы получим 10 дубликатов одинаковых стилей. Это не похоже на достаточно хорошее решение тоже. Особенно, если у нас много общих стилей, звучит так, будто это может быть плохим решением с точки зрения производительности.
  4. Ни в коем случае не используйте Shadow DOM и используйте глобальные стили :) Но это не решение текущей проблемы.

Я также проверил, как эта проблема решена в Angular Framework (я проверил версию 5 Angular). Когда я устанавливаю поведение инкапсуляции в Native, оно просто дублирует стили (как в # 3, описанном выше), что, я думаю, не лучший способ (но, возможно, лучший из существующих в настоящее время).

Итак, кто-нибудь знает, есть ли другой способ решения этой проблемы без описанных выше недостатков? Это звучит так, будто текущие недостатки Shadow DOM приносят еще больше проблем, чем пытаются решить.

1 Ответ

0 голосов
/ 13 ноября 2018

Реального недостатка в решении 3 нет:

  1. Примените ли вы стиль CSS к n элементам в основном документе или к 1 элементу в n Shadow DOM, стиль все равно будет продублирован для целых n элементов.

  2. Если вы импортируете документ n раз в n Shadow DOM, il будет фактически загружен только один раз и повторно использован через кеш браузера.

После этого il будет полагаться на реализацию браузером стилей Shadow DOM и CSS, и вы увидите снижение производительности только на тысячах Shadow DOM.


2019 обновление для Chrome 73+ и Opera 60 +

Теперь вы можете напрямую создать экземпляр объекта CSSStyleSheet и назначить его различным Shadow DOM.

Таким образом, HTML не будет дублироваться.

var css = new CSSStyleSheet()
css.replaceSync( "@import url( main.css )" )
host.shadowRoot.adoptedStyleSheets = [css] 
host2.shadowRoot.adoptedStyleSheets = [css] 

Вы также можете применить его к глобальному документу:

document.adpotedStyleSheets = [css]

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

 css.replaceSync( '.color { color: red }' )
...