CSS-префиксер для изоляции стилей: добавляем класс-обёртку ко всем правилам

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

Существует и другой, менее очевидный подход: добавить единый класс-контейнер ко всем селекторам CSS-файла. Например, если все правила начинаются с .my-app, то они будут применяться только к элементам внутри блока с этим классом. Это эффективно изолирует стили, не требуя переписывания всей библиотеки.

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

Постановка задачи

Исходный CSS-файл (materialize.css) содержит селекторы разных типов:

Нужно получить файл, в котором каждый селектор (кроме тех, что внутри @keyframes, так как они не относятся к DOM-элементам) будет начинаться с указанного класса, например .mlds. При этом важно сохранить вложенность и медиа-правила:

Почему не Autoprefixer?

Созвучное название может внести путаницу. Autoprefixer добавляет вендорные префиксы к CSS-свойствам (-webkit-, -moz- и т.д.). Наша задача – изменить селекторы, а не свойства. Это позволяет создать неймспейс для целой библиотеки. Такой приём часто называют «css namespacing» или «scoping через родительский класс».

Обзор решения

Я буду использовать библиотеку sabberworm/php-css-parser, которая разбирает CSS в объектную модель, позволяет изменять узлы и затем рендерить обратно в строку. Скрипт:

  1. Загружает исходный CSS.
  2. Парсит его в дерево.
  3. Рекурсивно обходит все блоки правил (DeclarationBlock).
  4. Для каждого селектора добавляет перед ним префикс-класс и пробел.
  5. Пропускает @keyframes (их селекторы не нужно префиксировать).
  6. Сохраняет результат в новый файл.

Код с пояснениями

Я использую composer для подключения Sabberworm. Потому в начале файла появляется строка с vendor/autoload.php. Если вы подключаете Sabberworm напрямую, то у вас этот момент может отличаться.

input и output файлы определяют какой файл нужно править и куда потом сохранить правки.

Теперь в примере — достаточно обернуть часть страницы в <div class="mlds">, и стили Materialize будут действовать только внутри этого контейнера, не конфликтуя с остальными.

Ограничения и нюансы

  1. Сложные селекторы – скрипт просто добавляет пробел и класс в начало строки. Для селекторов вида div > .class + span это даст .mlds div > .class + span, что корректно.
  2. Селекторы с запятой – парсер библиотеки разбивает их на отдельные объекты, поэтому каждый получит префикс.
  3. :host и теневой DOM – если в CSS есть псевдоклассы для веб-компонентов, добавление класса может сломать логику. В таких случаях префиксация не рекомендуется.
  4. @keyframes не префиксируется – это осознанное решение. Если нужно изолировать имена анимаций, потребуется отдельный подход (переименование).
  5. Вес селекторов – добавление родительского класса увеличивает специфичность всех правил. Это редко приводит к проблемам, но о нюансе стоит помнить.

Мало букафф? Читайте есчо !

SVG to CSS конвертер

Июнь 21, 2020 г.

Небольшая тулза по конвертации SVG картинок в CSS backgroung-image код. Рекомендую предварительно произвести оптимизацию изображения, убрать лишние/невидимые слои, маркеры программ редакторов SVG, лишние теги и т.п. Вы можете загрузить SVG в ...

Читать

Псевдоклассы состояния контейнера input

Октябрь 24, 2018 г.

Хотелось бы выделить такой перечень css псевдоклассов и приемов работы с ними, который основан на состоянии элемента INPUT. :checked псевдокласс Позволяет писать стили для радио/чек - боксов, которые выделены (checked) в текущий момент. [crayon-6ac0d0a8097e7453253942/] ...

Читать

Как работает position: sticky с bottom: 0 и почему он "не работает"

Август 6, 2025 г.

Иногда кажется, что position: sticky работает только с top. Указываешь bottom: 0 — и ничего не происходит. Особенно, если пытаешься сделать так, чтобы элемент "прилип" к нижней границе контейнера при прокрутке. Почему так? На деле position: sticky ...

Читать

Эффект размытия blur средствами CSS

Декабрь 23, 2015 г.

В интернете много решений, я попробовал, наверное, все :) Основная проблема - не удаётся достичь кросс-браузерности. Как всегда, отличился IE. Для ...

Читать
 

Комментарии к «CSS-префиксер для изоляции стилей: добавляем класс-обёртку ко всем правилам»

Понравилась статья? Есть вопросы? - пишите в комментариях.



Комментарий: