🔥

Тред (Сергей Куликов)


Тред про ограничения 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…

Сергей КуликовСергей Куликов