Тред про ограничения Shadow DOM и связанные с ними проблемы.
Как и кастомные элементы, Shadow DOM имеет ряд ограничений, наиболее важные из которых обусловлены самим устройством API, реализованного в браузерах. В том числе, природой изоляции.
Проблема № 1: та же, что и для кастомных элементов — Shadow DOM не работает с выключенным JS. Этот факт делает невозможными некоторые сценарии использования, прежде всего SSR.
Кроме того, это также означает проблемы с SEO. В качестве решения в Google советуют Rendertron на базе Puppeteer, который умеет отдавать роботам статику. Мои коллеги в Vaadin его используют.
github.com/GoogleChrome/r…
Существует черновик API декларативного Shadow DOM, над которым работает Mason Freed из Google. Реализация есть в Chrome за флагом, недавно о ней вышла статья на web.dev.
web.dev/declarative-sh…
Декларативный Shadow DOM для изоляции стилей на примере слайдов @shower_me! Развиваю старую идею, как имитировать почивший <style scoped>, на этот раз без JS, но пока только в Chrome за флагом youtu.be/ZjYKzrBEEuI
Видео с примером использования декларативного Shadow DOM для изоляции стилей недавно опубликовал Вадим Макеев.
twitter.com/pepelsbey/stat…
К стабильной версии декларативный Shadow DOM еще не готов. Идет обсуждение рисков, связанных с XSS и санитайзерами. Также пока неясно, что будет с декларативными кастомными элементами.
github.com/whatwg/dom/iss…
Проблема № 2: изоляция Shadow DOM создает преграду для связей по ID. В итоге ARIA-атрибуты вроде aria-labelledby не работают для элементов, находящихся по разные стороны shadow root.
О том, как эта проблема проявляется на практике, написал Devon Govett из Adobe. Он поделился выводами из своего эксперимента на тему использования хуков React Aria внутри веб-компонентов.
github.com/devongovett/wc…
Решением может стать Accessibility Object Model (AOM). Это целый набор экспериментальных API, которые пока находятся в разработке. Подробнее можно почитать в статье Léonie Watson.
24a11y.com/2019/web-compo…
Одна из идей в рамках AOM — атрибут, позволяющий явно указывать ID элементов, к которым необходим доступ извне. Что-то вроде атрибута exportparts, который доступен для CSS Shadow Parts.
github.com/WICG/aom/issue…
Проблема № 3: изоляция затрагивает также и элемент <form>. Если кнопка в форме находится внутри shadow root, отправлять форму она не сможет. Пример приводит в своей статье Poul H. Hansen.
hjorthhansen.dev/shadow-dom-and…
Справедлива эта проблема и для элементов <input> внутри Shadow DOM. В прошлом Polymer предлагал компонент для сериализации форм с рекурсивным обходом вложенных shadow root.
github.com/PolymerElement…
Проблема № 4: отсутствие API для работы с выделенным текстом внутри Shadow DOM при использовании window.getSelection(). Это актуально для WYSIWYG-редакторов вроде CKEditor, Quill и Trix.
github.com/WICG/webcompon…
В Chrome этот метод реализован на shadow root, в Firefox работает глобальный метод. Но в Safari действует изоляция, и getSelection() не возвращает данные об элементах внутри Shadow DOM.
bugs.webkit.org/show_bug.cgi?i…
Sam Thorogood из Google написал экспериментальный полифилл, позволяющий обойти это ограничение в Safari. Для одного из компонентов Vaadin я интегрировал этот полифилл в форк Quill.
github.com/GoogleChromeLa…
Проблема № 5: проблемы с автозаполнением форм. В баг-трекере Chromium есть issue на эту тему, и ему уже больше трех лет. В общем, с формами у Shadow DOM как-то совсем не задалось.
bugs.chromium.org/p/chromium/iss…
Затрагивает эта проблема и браузерные расширения, прежде всего менеджеры паролей. Каждому из них потребуется соответствующий фикс. Например, в 1Password он уже реализован.
1password.community/discussion/791…
Проблема № 6: изоляция стилей не работает в случае с font-face и keyframes. Решение этой проблемы требует стандартизации. На данный момент font-face в Shadow DOM использовать нельзя.
github.com/w3c/csswg-draf…
Проблема № 7: сторонние скрипты. Google Tag Manager, A/B тесты, аналитика и все, что так любят добавлять на сайт маркетологи, очень плохо дружит с Shadow DOM. Об этом тоже важно помнить.
@jsunderhood Как тестировать страницу с ShadowDOM при помощи Selenium? Вроде был /deep/ комбинатор, но он же deprecated?
Проблема № 8: тестирование. На сегодняшний день Shadow DOM уже поддерживается в Cypress, TestCafe, WebdriverIO и Playwright. В Selenium поддержка пока не реализована.
twitter.com/justboriss/sta…
@jsunderhood Как может быть поддержка в WebdriverIO, но не в Selenium? У них же один и тот же webdriver protocol
Насчет WebdriverIO: поддержка Shadow DOM появилась в версии 5.5.0 и реализация у них своя (поскольку в протоколе WebDriver нет стандартизированного API).
webdriver.io/blog/2019/02/2…
twitter.com/justboriss/sta…
Есть issue на эту тему, где в том числе поделился опытом Diego Ferreiro Val из Salesforce. Согласиться на добавление API, которое бы нарушало изоляцию, разработчики браузеров не готовы.
github.com/WICG/webcompon…
Вроде бы, все основные проблемы перечислил. Есть и другие — например, в Chrome в Shadow DOM не работает перевод страницы.
bugs.chromium.org/p/chromium/iss…
Еще есть баг на iOS, связанный с кнопками быстрого перехода между полями формы в Shadow DOM. Он был исправлен совсем недавно.
bugs.webkit.org/show_bug.cgi?i…
В качестве заключения: проблем у Shadow DOM по-прежнему много, и о них желательно знать заранее (или придется городить костыли). Неспроста YouTube использует полифилл даже в Chrome.
Да, чуть не забыл: реклама же! Мне однажды тоже довелось встретить div с shadow root в рекламном баннере Яндекс-почты. Для блокировщиков это проблема.
twitter.com/faramo_zayw/st…
Так или иначе, статистика показов страниц в Chrome Platform Status говорит сама за себя: по сравнению с кастомными элементами, у которых около 10%, Shadow DOM почти вдвое менее популярен.
chromestatus.com/metrics/featur…
