Расцвет Utility-First CSS на примере Tailwind CSS

2 мин

1. Трудности традиционных методологий CSS

До появления Utility-First существовало множество отличных методологий организации CSS-стилей, например:

  • BEM (Block, Element, Modifier): Использует соглашение об именовании block__element--modifier, чтобы обеспечить независимость и удобство сопровождения стилей.
  • OOCSS (Object-Oriented CSS): Предлагает отделять структуру от оформления, а контейнер — от содержимого.
  • CSS-in-JS: Позволяет писать CSS непосредственно внутри JavaScript-компонентов и инкапсулировать стили на уровне компонента.

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

2. Что такое Utility-First?

Utility-First — это подход к CSS, предлагающий набор неизменяемых утилитарных классов, каждый из которых решает одну задачу, а сложные интерфейсы строятся путём их сочетания.

Например, вместо того чтобы создавать класс .card и определять его display, padding и box-shadow в CSS-файле, можно написать прямо в HTML:

<div class="block p-6 rounded-lg shadow-lg bg-white">
  <!-- ... -->
</div>

Здесь block, p-6, rounded-lg и другие утилитарные классы отвечают каждый только за одну небольшую задачу.

3. Tailwind CSS — образец Utility-First

Tailwind CSS — самый популярный на сегодняшний день CSS-фреймворк в стиле Utility-First. Он предоставляет чрезвычайно подробный набор утилитарных классов, охватывающий почти все распространённые свойства CSS.

Основные преимущества:

  • Очень быстрая разработка: Покидать HTML-файл почти не требуется. Комбинируя атомарные классы, можно быстро собрать практически любой дизайн и значительно ускорить создание прототипов и разработку.
  • Принудительная дизайн-система: Поскольку все стили — цвета, отступы и размеры шрифта — берутся из заранее определённой конфигурации (theme), участникам команды легко поддерживать единообразие UI и избегать «магических чисел».
  • Никаких мучений с именами: «В информатике есть две трудные задачи: инвалидация кэша и именование». Tailwind почти полностью избавляет от необходимости придумывать имена CSS-классам.
  • Исключительная производительность: При производственной сборке Tailwind сканирует файлы и удаляет все неиспользуемые CSS-классы с помощью PurgeCSS (или встроенного JIT-движка), поэтому итоговый CSS-файл обычно получается очень небольшим.

4. «Ад из имён классов»? — Другой взгляд на недостатки

Самая частая критика Tailwind состоит в том, что HTML становится раздутым и плохо читаемым, словно мы вернулись в эпоху «встроенных стилей».

<button class="py-2 px-4 font-semibold rounded-lg shadow-md text-white bg-blue-500 hover:bg-blue-700">
  Click me
</button>

К этому действительно нужно привыкнуть. Однако сторонники считают, что:

  1. Стили и структура и так тесно связаны, поэтому их совместное размещение может даже облегчить сопровождение.
  2. Если выделять повторно используемые компоненты, например компоненты React или Vue, эту «неразбериху» можно инкапсулировать.

Для повторно используемых сочетаний стилей Tailwind предоставляет директиву @apply:

/* in your css file */
.btn-primary {
  @apply py-2 px-4 font-semibold rounded-lg shadow-md text-white bg-blue-500 hover:bg-blue-700;
}

После этого в HTML можно использовать .btn-primary. Однако официальная рекомендация Tailwind — решать задачу повторного использования с помощью компонентов.

Заключение

Успех Utility-First и Tailwind CSS отражает изменение представлений о «разделении ответственности» во фронтенд-разработке: от разделения языков (HTML/CSS/JS) к разделению компонентов. На первый взгляд «примитивный» подход решает многие практические проблемы современной веб-разработки и предлагает разработчикам короткий путь к эффективным, единообразным и производительным интерфейсам.