Стилизация веб-компонентов с использованием общей таблицы стилей

  1. Дальнейшее чтение на SmashingMag:
  2. Каким должен быть глобальный стиль руководства стиля в веб-компоненте?
  3. Как использовать Shadow DOM с помощью внешних таблиц стилей
  4. Что вы можете сделать сегодня
  5. Использование @import
  6. Не используйте Shadow DOM
  7. Использование библиотеки веб-компонентов
  8. Обещание будущего
  9. Пользовательские свойства
  10. @apply Rules
  11. Конструируемые таблицы стилей
  12. Уроки выучены
  13. Вещи, чтобы помнить

Веб-компоненты - это удивительная новая функция в Интернете, позволяющая разработчикам определять свои собственные элементы HTML. В сочетании с руководством по стилю веб-компоненты могут создавать API-компоненты, которые позволяют разработчикам прекращать копирование и вставку фрагментов кода и вместо этого просто использовать элемент DOM. Используя теневой DOM, мы можем инкапсулировать веб-компонент и не беспокоиться о войнах специфичности с любой другой таблицей стилей на странице. Тем не менее, веб-компоненты и руководства по стилю в настоящее время, похоже, расходятся друг с другом.

Веб-компоненты являются удивительной новой функцией в Интернете, позволяющей разработчикам определять свои собственные элементы HTML. В сочетании с руководством по стилю веб-компоненты могут создавать API компонента , что позволяет разработчикам перестать копировать и вставлять фрагменты кода и вместо этого просто использовать элемент DOM. Используя теневой DOM, мы можем инкапсулировать веб-компонент и не беспокоиться о войны специфичности с любой другой таблицей стилей на странице.

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

Дальнейшее чтение на SmashingMag:

Итак, как они могут сосуществовать, когда глобальные руководства по стилю продолжают обеспечивать согласованность и стили даже для веб-компонентов с теневым DOM? К счастью, есть решения, которые работают сегодня, и еще больше решений, которые позволяют глобальным руководствам по стилю предоставлять стилизацию для веб-компонентов. (В оставшейся части этой статьи я буду использовать термин «веб-компоненты» для обозначения пользовательских элементов с теневым DOM.)

Каким должен быть глобальный стиль руководства стиля в веб-компоненте?

Прежде чем обсуждать, как получить глобальное руководство по стилю для стиля веб-компонента, мы должны обсудить, что он должен и не должен пытаться стилизовать.

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

Ниже приведен простой веб-компонент формы входа в систему, который инкапсулирует все его стили.

<template id = "login-form-template"> <style>: host {color: # 333333; шрифт: 16px Arial, без засечек; } p {margin: 0; } p + p {margin-top: 20px; } a {color: # 1f66e5; } label {display: block; нижнее поле: 5 пикселей; } input [type = "text"], input [type = "password"] {background-color: #eaeaea; рамка: 1px сплошная серая; радиус границы: 4 пикселя; размер коробки: бордюр; цвет: наследовать; шрифт: наследовать; отступы: 10px 10px; ширина: 100%; } input [type = "submit"] {font: 16px / 1.6 Arial, без засечек; белый цвет; фон: васильковый; граница: 1px solid # 1f66e5; радиус границы: 4 пикселя; отступы: 10px 10px; ширина: 100%; } .container {max-width: 300px; отступы: 50 пикселей; рамка: 1px сплошная серая; } .footnote {text-align: center; } </ style> <div class = "container"> <form action = "#"> <p> <label for = "username"> Имя пользователя </ label> <input type = "text" id = "username" name = "username"> </ p> <p> <label for = "password"> Password </ label> <input type = "password" id = "password" name = "password"> </ p> <p > <input type = "submit" value = "Login"> </ p> <p class = "footnote"> Не зарегистрированы? <a href="#"> Создать аккаунт </a> </ p> </ form> </ div> </ template> <script> const doc = (document._currentScript || document.currentScript) .ownerDocument; const template = doc.querySelector ('# login-form-template'); customElements.define ('login-form', класс расширяет HTMLElement {constructor () {super (); const root = this.attachShadow ({mode: 'closed'}); const temp = document.importNode (template.content, true ); root.appendChild (temp);}}); </ Скрипт>

Примечание. Примеры кода написаны в спецификации версии 1 для веб-компонентов.

Примеры кода написаны в спецификации версии 1 для веб-компонентов

Простой веб-компонент формы входа

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

Если мы полностью инкапсулируем все стили, которые нужны веб-компоненту, то CSS для стилизации абзацев, якорных тегов, полей ввода и т. Д. Будет дублироваться во всех веб-компонентах, которые их используют. Это не только увеличит затраты на обслуживание, но и приведет к гораздо большим размерам загрузки для пользователей.

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

В предыдущем примере веб-компонент формы входа в систему объявил бы стили только для своих двух уникальных классов: .container и .footnote. Остальные стили будут принадлежать общей таблице стилей и будут стилизовать абзацы, теги привязки, поля ввода и так далее.

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

Как использовать Shadow DOM с помощью внешних таблиц стилей

Первоначальная спецификация для веб-компонентов (известная как версия 0) позволяла любой внешней таблице стилей проникать в теневой DOM с помощью селекторов :: shadow или / deep / CSS. Использование :: shadow и / deep / позволило вам иметь руководство по стилю, чтобы проникнуть в теневой DOM и настроить общие стили, независимо от того, захотел ли вас веб-компонент или нет.

/ * Стилизуем все теги p внутри теневого DOM веб-компонента * / login-form :: shadow p {color: red; }

С появлением новейшей версии спецификации веб-компонентов (известной как версия 1) авторы убрал возможность внешних таблиц стилей для проникновения в теневой DOM, и они не предоставили альтернативы. Вместо этого философия изменилась с использование драконов для стилизации веб-компонентов вместо того, чтобы использовать мосты. Другими словами, авторы веб-компонентов должны отвечать за то, какие правила внешнего стиля разрешают стилизовать их компоненты, а не заставлять их.

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

Что вы можете сделать сегодня

Сегодня вы можете использовать три метода, которые позволят веб-компоненту совместно использовать стили: @import, пользовательские элементы и библиотека веб-компонентов.

Использование @import

На сегодняшний день единственный родной способ добавить таблицу стилей в веб-компонент - использовать @import. Хотя это работает, это анти паттерн , Однако для веб-компонентов это еще большая проблема с производительностью.

<template id = "login-form-template"> <style> @import "styleguide.css" </ style> <style> .container {max-width: 300px; отступы: 50 пикселей; рамка: 1px сплошная серая; } .footnote {text-align: center; } </ style> <! - остаток шаблона DOM -> </ template>

Обычно @import является анти-паттерном, потому что он загружает все таблицы стилей последовательно, а не параллельно, особенно если они вложенные. В нашей ситуации загрузка одной таблицы стилей в серии не может помочь, поэтому в теории все должно быть хорошо. Но когда я проверял в Chrome результаты показали, что при использовании @import страница сделать на полсекунды медленнее чем когда просто встраивание стилей напрямую в веб-компонент.

Примечание: из-за различий в полифилл HTML импорта работает по сравнению с собственным импортом HTML, WebPagetest.org может использоваться только для получения надежных результатов в браузерах, которые изначально поддерживают импорт HTML (например, Chrome).

Результаты трех тестов производительности показывают, что @import заставляет браузер рендериться на полсекунды медленнее, чем при простом встраивании стилей непосредственно в веб-компонент.

В конце концов, @import по-прежнему является антишаблоном и может быть проблемой производительности веб-компонентов. Так что это не очень хорошее решение.

Не используйте Shadow DOM

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

Не используя теневой DOM, вы будете создавать пользовательские элементы вместо веб-компонентов (см. ниже), единственное отличие заключается в отсутствии теневого DOM и области видимости. Ваш элемент будет зависеть от стилей страницы, но мы уже имеем дело с этим сегодня, поэтому мы ничего не знаем, как с этим справиться. Пользовательские элементы полностью поддерживаются полифилом webcomponentjs, который имеет отличная поддержка браузера ,

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

Если вы решили создать пользовательские элементы, помните о нескольких различиях между пользовательскими элементами и веб-компонентами.

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

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

Во-вторых, обязательно инкапсулируйте любой код JavaScript в выражении немедленного вызова функции (IFFE), чтобы не допустить ни одной переменной в глобальную область видимости. В дополнение к отсутствию области видимости CSS, пользовательские элементы не обеспечивают область видимости JavaScript.

В-третьих, вам нужно будет использовать функцию connectedCallback пользовательского элемента для добавить шаблон DOM к элементу , Согласно спецификации веб-компонента, пользовательские элементы не должны добавлять дочерние элементы во время функции конструктора, поэтому вам нужно отложить добавление DOM в функцию connectedCallback.

Наконец, элемент <slot> не работает вне теневого DOM. Это означает, что вам придется использовать другой метод, чтобы предоставить разработчикам возможность вставить свой контент в ваш пользовательский элемент. Обычно это влечет за собой простое манипулирование DOM, чтобы вставить его содержимое туда, куда вы хотите.

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

<! - login-form.html -> <template id = "login-form-template"> <style> login-form .container {max-width: 300px; отступы: 50 пикселей; рамка: 1px сплошная серая; } Форма входа .footnote {text-align: center; } </ style> <! - Остальная часть шаблона DOM -> </ template> <script> (function () {const doc = (document._currentScript || document.currentScript) .ownerDocument; const template = doc.querySelector ('# login-form-template'); customElements.define ('login-form', класс extends HTMLElement {constructor () {super ();} // Без теневого DOM нам придется манипулировать пользовательским элементом // после того, как он был вставлен в DOM. connectedCallback () {const temp = document.importNode (template.content, true); this.appendChild (temp);}});}) (); </ script> <! - index.html -> <link rel = "stylesheet" href = "styleguide.css"> <link rel = "import" href = "login-form.html"> <login-form > </ Войти форма>

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

Результаты двух тестов производительности показывают, что пользовательские элементы работают почти так же быстро, как и веб-компоненты.

Кроме того: пользовательский элемент по-прежнему является веб-компонентом для любых целей и задач. Термин «веб-компоненты» используется для описания четыре отдельные технологии : пользовательские элементы, теги шаблонов, импорт HTML и теневой DOM.

К сожалению, этот термин использовался для описания всего, что использует любую комбинацию из четырех технологий. Это привело к путанице вокруг того, что люди имеют в виду, когда говорят «веб-компонент». Так же, как Роб Додсон обнаружил Я считаю полезным использовать разные термины, когда речь идет о пользовательских элементах с и без теневого DOM.

Большинство разработчиков, с которыми я говорил, склонны связывать термин «веб-компонент» с пользовательским элементом, использующим теневой DOM. Итак, для целей этой статьи я создал искусственное различие между веб-компонентом и пользовательским элементом.

Использование библиотеки веб-компонентов

Еще одно решение, которое вы можете использовать сегодня, - это библиотека веб-компонентов, такая как полимер , SkateJS или же X-Tag , Эти библиотеки помогают заполнить пробелы в сегодняшней поддержке, а также могут упростить код, необходимый для создания веб-компонента. Они также обычно предоставляют дополнительные функции, которые облегчают написание веб-компонентов.

Например, Polymer позволяет вам создать простой веб-компонент всего за несколько строк JavaScript. Дополнительным преимуществом является то, что Polymer предоставляет решение для используя теневой DOM и общую таблицу стилей , Это означает, что сегодня вы можете создавать веб-компоненты, которые совместно используют стили.

Для этого создайте так называемый модуль стилей, который содержит все общие стили. Это может быть тег <style> со встроенными общими стилями или тег <link rel = «import»>, указывающий на общую таблицу стилей. В любом случае, включите стили в свой веб-компонент с помощью тега <style include>, а затем Polymer проанализирует стили и добавит их в виде встроенного тега <style> в ваш веб-компонент.

<! - shared-styles.html -> <dom-module id = "shared-styles"> <! - ссылка на общую таблицу стилей -> <! - <link rel = "import" href = "styleguide.css"> -> <! - Встроить общие стили -> <template> <style>: host {color: # 333333; шрифт: 16px Arial, без засечек; } / * Остальная часть общего CSS * / </ style> </ template> </ dom-module> <! - login-form.html -> <link rel = "import" href = "../ Polymer / Polymer.html "> <link rel =" import "href =" ../ shared-styles / shared-styles.html "> <dom-module id =" login-form "> <template> <! - Включить общие стили -> <style include = "shared-styles"> </ style> <style> .container {max-width: 300px; отступы: 50 пикселей; рамка: 1px сплошная серая; } .footnote {text-align: center; } </ style> <! - Остальная часть шаблона DOM -> </ template> <script> Polymer ({is: 'login-form'}); </ script> </ dom-module>

Единственным недостатком использования библиотеки является то, что она может задерживать время рендеринга ваших веб-компонентов. Это не должно вызывать удивления, потому что загрузка кода библиотеки и ее обработка занимают время. Любые веб-компоненты на странице не могут начать рендеринг, пока библиотека не закончит обработку.

В случае Polymer это может задержать время рендеринга страницы на полсекунды по сравнению с нативными веб-компонентами. модуль стиля, который встраивает стили немного медленнее, чем модуль стиля, который связывает стили , а также встраивание стилей непосредственно в веб-компонент так же быстро, как с помощью модуля стиля.

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

Это просто компромисс, который вы должны сделать, чтобы использовать библиотеку веб-компонентов

Результаты тестов производительности показывают, что при использовании Polymer веб-компоненты будут отрисовываться на полсекунды медленнее, чем собственные веб-компоненты.

Обещание будущего

Если ни одно из существующих решений не работает для вас, не отчаивайтесь. Если все пойдет хорошо, от нескольких месяцев до нескольких лет, мы сможем использовать общие стили, используя несколько разных подходов.

Пользовательские свойства

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

Чтобы объявить настраиваемое свойство, используйте обозначение настраиваемого свойства –my-variable: value и получите доступ к переменной, используя свойство: var (–my-variable). Пользовательское свойство распространяется каскадно, как и любое другое правило CSS, поэтому его значение наследуется от его родителя и может быть переопределено. Единственное предостережение для пользовательских свойств заключается в том, что они должны быть объявлены внутри селектора и не могут быть объявлены сами по себе, в отличие от переменной препроцессора.

<style> / * Объявление пользовательского свойства * / html {--main-bg-color: red; } / * Используйте пользовательское свойство * / input {background: var (- main-bg-color); } </ style>

Одна вещь, которая делает пользовательские свойства такими мощными, - это их способность проникать в теневой DOM. Это не то же самое, что селекторы / deep / и :: shadow, потому что они не пробиваются в веб-компонент. Вместо этого автор веб-компонента должен использовать настраиваемое свойство в своем CSS, чтобы его можно было применить. Это означает, что автор веб-компонента может создать пользовательский API-интерфейс, который пользователи веб-компонента могут использовать для применения своих собственных стилей.

<template id = "my-element-template"> <style> / * Объявите API пользовательского свойства * /: host {--main-bg-color: brown; } .one {color: var (- main-bg-color); } </ style> <div class = "one"> Hello World </ div> </ template> <script> / * Код для настройки веб-компонента my-element * / </ script> <my-element> </ my-element> <style> / * Переопределить пользовательскую переменную собственным значением * / my-element {--main-bg-color: red; } </ style>

Браузерная поддержка пользовательских свойств на удивление хорошо , Единственная причина, по которой это не решение, которое вы можете использовать сегодня, заключается в том, что не работает полифилл без пользовательских элементов версия 1. Команда, стоящая за полифилом webcomponentjs сейчас работаю над тем, чтобы добавить его , но он еще не выпущен и находится в собранном состоянии, что означает, что если вы хэшируете свои активы для производства, вы не можете его использовать. Насколько я понимаю, он должен выйти в начале следующего года.

Несмотря на это, пользовательские свойства не являются хорошим методом для обмена стилями между веб-компонентами. Поскольку они могут использоваться только для объявления одного значения свойства, веб-компонент все равно должен будет встраивать все стили руководства по стилям, хотя их значения заменяются переменными.

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

/ * Использовать пользовательское свойство * / input {background: var (–main-bg-color); } </ style>

Одна вещь, которая делает пользовательские свойства такими мощными, - это их способность проникать в теневой DOM. Это не то же самое, что селекторы / deep / и :: shadow, потому что они не пробиваются в веб-компонент. Вместо этого автор веб-компонента должен использовать настраиваемое свойство в своем CSS, чтобы его можно было применить. Это означает, что автор веб-компонента может создать пользовательский API-интерфейс, который пользователи веб-компонента могут использовать для применения своих собственных стилей.

<template id = "my-element-template"> <style> / * Объявите API пользовательского свойства * /: host {--main-bg-color: brown; } .one {color: var (- main-bg-color); } </ style> <div class = "one"> Hello World </ div> </ template> <script> / * Код для настройки веб-компонента my-element * / </ script> <my-element> </ my-element> <style> / * Переопределить пользовательскую переменную собственным значением * / my-element {--main-bg-color: red; } </ style>

Браузерная поддержка пользовательских свойств на удивление хорошо , Единственная причина, по которой это не решение, которое вы можете использовать сегодня, заключается в том, что не работает полифилл без пользовательских элементов версия 1. Команда, стоящая за полифилом webcomponentjs сейчас работаю над тем, чтобы добавить его , но он еще не выпущен и находится в собранном состоянии, что означает, что если вы хэшируете свои активы для производства, вы не можете его использовать. Насколько я понимаю, он должен выйти в начале следующего года.

Несмотря на это, пользовательские свойства не являются хорошим методом для обмена стилями между веб-компонентами. Поскольку они могут использоваться только для объявления одного значения свойства, веб-компонент все равно должен будет встраивать все стили руководства по стилям, хотя их значения заменяются переменными.

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

@apply Rules

В дополнение к пользовательским свойствам, CSS также получает @ применять правила , Применять правила по существу миксины для мира CSS , Они объявляются аналогично настраиваемым свойствам, но могут использоваться для объявления групп свойств, а не просто значений свойств. Как и пользовательские свойства, их значения могут быть унаследованы и переопределены, и они должны быть объявлены внутри селектора, чтобы работать.

<style> / * Объявить правило * / html {--typography: {font: 16px Arial, без засечек; цвет: # 333333; }} / * Использовать правило * / input {@apply --typography; } </ style>

Браузерная поддержка правил @apply практически отсутствует. Chrome в настоящее время поддерживает это за флагом функции (который я не смог найти), но это все. По той же причине не существует рабочего полизаполнения, так как для пользовательских свойств нет полифила. Команда поликомпонента webcomponentjs также работает над добавлением правил @apply, а также пользовательских свойств, поэтому оба будут доступны после выпуска новой версии.

В отличие от пользовательских свойств, правила @apply являются гораздо лучшим решением для обмена стилями. Поскольку они могут настроить группу объявлений свойств, вы можете использовать их для настройки стиля по умолчанию для всех собственных элементов, а затем использовать их внутри веб-компонента. Для этого вам нужно создать правило @apply для каждого нативного элемента.

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

/ * styleguide.css * / html {--typography: {color: # 333333; шрифт: 16px Arial, без засечек; } --параграф: {поле: 0; } --label {display: block; нижнее поле: 5 пикселей; } --input-text {background-color: #eaeaea; рамка: 1px сплошная серая; радиус границы: 4 пикселя; размер коробки: бордюр; цвет: наследовать; шрифт: наследовать; отступы: 10px 10px; ширина: 100%; } --input-submit {font: 16px / 1.6 Arial, без засечек; белый цвет; фон: васильковый; граница: 1px solid # 1f66e5; радиус границы: 4 пикселя; отступы: 10px 10px; ширина: 100%; } / * И так для каждого собственного элемента * /} <! - login-form.html -> <template id = "login-form-template"> <style>: host {@apply --typography; } p {@apply --paragraph; } label {@apply --label; } input-text {@apply --input-text; } .input-submit {@apply --input-submit; } .container {max-width: 300px; отступы: 50 пикселей; рамка: 1px сплошная серая; } .footnote {text-align: center; } </ style> <! - Остальная часть шаблона DOM -> </ template>

Из-за необходимости обширного шаблона я не верю, что правила @apply были бы хорошим решением для обмена стилями между веб-компонентами. Тем не менее, они являются отличным решением для их создания.

в тени DOM

Согласно спецификация веб-компонента браузеры игнорируют любые теги <link rel = “stylesheet”> в теневом DOM, обрабатывая их так же, как и внутри фрагмента документа. Это лишило нас возможности ссылаться в любых общих стилях в наших веб-компонентах, что было неудачно, то есть до тех пор, пока несколько месяцев назад рабочая группа по веб-компонентам не предложила <link rel = «stylesheet»> теги должны работать в теневом DOM , После всего лишь недели обсуждения все они согласились, что должны, и через несколько дней добавил его в спецификацию HTML ,

<template id = "login-form-template"> <link rel = "stylesheet" href = "styleguide.css"> <style> .container {max-width: 300px; отступы: 50 пикселей; рамка: 1px сплошная серая; } .footnote {text-align: center; } </ style> <! - остаток шаблона DOM -> </ template>

Если это кажется слишком быстрым для рабочей группы, чтобы согласовать спецификацию, то это потому, что это не было новым предложением. Заставить теги ссылок работать в теневом DOM было на самом деле предложенный по крайней мере три года назад , но он был засорен до тех пор, пока они не смогли убедиться, что это не является проблемой для производительности.

Если принятие предложения не является достаточно захватывающим, Chrome 55 (в настоящее время Chrome Canary) добавили начальный функционал заставить теги ссылок работать в теневом DOM. Даже кажется, что этот функционал приземлился в текущей версии Chrome , Четное Safari реализовал функцию в Safari 18 ,

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

Конечно, способ, которым производители браузеров реализуют эту функцию, будет определять жизнеспособность этого решения. Для правильной работы теги ссылок должны быть дедуплицированы, чтобы несколько веб-компонентов, запрашивающих один и тот же файл CSS, вызывали только один HTTP-запрос. CSS также необходимо будет проанализировать только один раз, чтобы каждый экземпляр веб-компонента не должен был повторно вычислять общие стили, а вместо этого использовал бы повторно вычисленные стили.

Хром делает оба эти уже. Таким образом, если все остальные производители браузеров реализуют его аналогичным образом, то теги ссылок, работающие в теневом DOM, определенно решат проблему обмена стилями между веб-компонентами.

Конструируемые таблицы стилей

В это может быть трудно поверить, так как у нас его еще нет, но тег ссылки, работающий в теневом DOM, не долгосрочное решение , Вместо этого это просто краткосрочное решение, которое поможет нам найти реальное решение: конструируемые таблицы стилей.

Конструируемые таблицы стилей предложение разрешить создание объектов StyleSheet в JavaScript с помощью функции конструктора. Затем созданная таблица стилей может быть добавлена ​​в теневой DOM через API, что позволит теневому DOM использовать набор общих стилей.

К сожалению, это все, что я мог собрать из предложения. Я попытался узнать больше информации о том, какие конструктивные таблицы стилей были просить Рабочую группу по веб-компонентам , но они перенаправили меня в рабочую группу CSS W3C список рассылки , где я снова спросил, но никто не ответил. Я даже не мог понять, как продвигается предложение, потому что оно не обновлялся более двух лет ,

Несмотря на это, рабочая группа по веб-компонентам использует это как решение за делиться стилями между веб-компонентами. Надеемся, что либо предложение будет обновлено, либо рабочая группа по веб-компонентам выпустит дополнительную информацию о нем и его принятии. До тех пор «долгосрочное» решение, похоже, не произойдет в обозримом будущем.

Уроки выучены

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

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

Если вы решите немного подождать, прежде чем углубляться в веб-компоненты, то через несколько лет у нас должны быть отличные решения для обмена стилями между ними. Итак, продолжайте проверять, как оно продвигается.

Вещи, чтобы помнить

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

Самое главное, что спецификация веб-компонента все еще активно разрабатывается, а это значит, что все может и будет меняться. Веб-компоненты по-прежнему очень важны, так что будьте готовы идти в ногу со временем.

Если вы решили использовать теневой DOM, знайте, что это довольно медленный а также unperformant в многозаполненные браузеры , Именно по этой причине разработчики Polymer создали свою теневую реализацию DOM и сделали ее своей версией по умолчанию.

Chrome, Opera и, недавно, Сафари единственные браузеры, которые поддерживают Shadow DOM версия 0 , Firefox все еще находится в разработке, хотя и имеет поддержал это за экспериментом с версии 29. Microsoft все еще рассматриваю это для края и имеет это в качестве высокого приоритета на своей дорожной карте.

Тем не менее, теневой DOM версии 0 является старой спецификацией. Shadow DOM версия 1 это новый, и только Chrome, Safari и Opera полностью поддерживаю это , Не говоря уже о том, что пользовательские элементы версия 0 прошел через тот же апгрейд, и только Chrome полностью поддерживает пользовательские элементы версии 1 , в то время как Технический предварительный просмотр Safari поддерживает его начиная с версии 17 , Пользовательские элементы версии 1 имеют некоторые существенные изменения в написании веб-компонентов, поэтому обязательно полностью понять, что это влечет за собой ,

Наконец, полифилл webcomponentjs поддерживает только реализацию версии 0 теневого DOM и пользовательских элементов. версия 1 ветка полифилла будет поддерживать версию 1, но она еще не выпущена.

Каким должен быть глобальный стиль руководства стиля в веб-компоненте?