Расцвет Utility-First CSS на примере Tailwind CSS
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>К этому действительно нужно привыкнуть. Однако сторонники считают, что:
- Стили и структура и так тесно связаны, поэтому их совместное размещение может даже облегчить сопровождение.
- Если выделять повторно используемые компоненты, например компоненты 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) к разделению компонентов. На первый взгляд «примитивный» подход решает многие практические проблемы современной веб-разработки и предлагает разработчикам короткий путь к эффективным, единообразным и производительным интерфейсам.