Очевидно, я бы не стал писать эту статью, если бы считал, что TailwindCSS – просто очередной фреймворк. Я считаю, что он кардинально отличается от всех других фреймворков и создает отдельную парадигму web-стилизации. И при этом выполняет все поставленные перед ним задачи, делая это лучше и удобнее других.
Тех, кто еще не знаком с TailwindCSS, я постараюсь завербовать в ряды его поклонников. Тех, кто против него, я постараюсь заставить в этом усомниться и пересмотреть своё мнение.
Я также хотел узнать ваше мнение по этому поводу. TailwindCSS – это шаг вперед, назад или просто топтание на месте? Свой ответ вы можете оставить в опросе в конце статьи. А если вам есть, что добавить по теме, пожалуйста, сделайте это в комментариях.
Кто не в курсе, TailwindCSS – это CSS-библиотека, которая упрощает стилизацию HTML, тем же путем, как это делает Bootstrap, – добавляя огромное количество разнообразных классов. Но, в отличие от Bootstrap, который добавляет уже готовые к употреблению компоненты, такие как кнопки, алерты и навбары, классы TailwindCSS нацелены на конкретное свойство. В TailwindCSS нет заранее написанной кнопки, её ты должен сделать сам.
По факту, вы пишете свой CSS как HTML-классы в формате похожем на популярный плагин Emmet. Ерунда? Как бы не так. Всё дело как всегда в деталях и окружении.
Я прекрасно понимаю людей, которые морщатся при виде такого формата записи. И я понимаю почему. Но мне кажется, что это просто плохая привычка из "программистского детства".
Мы попробуем избавиться от неё и понять все плюсы работы с TailwindCSS. Для этого сначала перечислим все минусы, которые якобы свойственны таким CSS-фреймворкам. А затем разберемся, есть ли они в TailwindCSS.
Проблемы
- Как бы много ни было классов, мы всё равно ограничены данным нам набором. Мы загоняем своё оформление в придуманные за нас рамки, что приводит к тому, что все сайты, написанные на TailwindCSS похожи друг на друга.
- У нас будет куча лишних стилей, которые мы не используем.
- Если нам нужно сделать две одинаковых кнопки, нам придется еще раз писать те же самые классы в другом месте.
- Засорять HTML стилями – это строго против правил. Всех верстальщиков "с пелёнок" учат не писать стили inline, а TailwindCSS нарушает эту аксиому.
Если я что-то пропустил, жду ваши предложения в комментариях. Обязательно добавим и обсудим.
Проблемы описаны в порядке сложности их решения. Мы пойдем по порядку, начнем с самых простых проблем и закончим самыми фундаментальными. Итак...
1. TailwindCSS – это не Bootstrap
Вроде бы небольшое отличие TailwindCSS от всех других CSS-фреймворков, во главе которых Bootstrap, а именно классы как свойства, а не классы как компоненты, меняет примерно всё. И если внешне TailwindCSS на них похож, по своей сути, он нечто совсем другое – новый подход к написанию CSS.
Если вы считаете, что TailwindCSS лишает сайты оригинальности, значит вы эту разницу пока не видите. Во-первых, претензия к одинаковости касается именно Bootstrap и подобных фреймворков с классами как компонентами. Во-вторых, даже там при желании всё можно кастомизировать до неузнаваемости, переписав классы под свои нужды и разбавив с классами из чистого CSS.
В чем основная сила Bootstrap – он хорошо подходит для proof of concept. Быстро нарисовать более-менее красивый интерфейс, когда нужно показать функционал, – это Bootstrap. Нам не столь важен внешний вид, главное, чтобы быстро и глаза не резало (например, в админпанели), – это тоже Bootstrap.
TailwindCSS в таких случаях не подходит по определению. У вас нет готовых компонентов, вам всё нужно писать с нуля (TailwindUI не в счет).
Конечно, TailwindCSS изначально тоже вас ограничивает. Например, есть margin
со значением 2.5rem
, есть 3rem
, но нет 2.75rem
. Ограничение. Однако оно легко решается настройками в файле tailwind.config.js
, где вы можете добавить любые значения, нужные вам в проекте.
Вы можете добавлять, удалять и переписывать любые классы. Если вдруг вас не устраивает цвет bg-red-500
, вы можете его изменить одной строчкой кода. В других фреймворках вам бы пришлось менять компоненты. Подробнее о кастомизации читайте в документации.
2. Никаких лишних стилей
Проблема с переизбытком лишних классов также решается с помощью tailwind.config.js
. Если раньше вам нужно было добавлять PurgeCSS или другую библиотеку для удаления лишних классов, теперь TailwindCSS сделает это за вас. Всё, что вам нужно сделать, – указать папку, где хранятся ваши файлы с разметкой. TailwindCSS сам пройдется по ним, найдет все использованные классы, их оставит, а остальные удалит.
Если какие-то классы добавляются через JavaScript, укажите их в whitelist, TailwindCSS также их сохранит. Подробнее в документации.
3. Переиспользуемость
Если писать CSS в inline-стиле, для одинаковых или почти одинаковых кнопок каждый раз придется писать почти один и тот же код. Как эту проблему можно решить в TailwindCSS? It depends.
Если вы пишете код без фронтенд-фреймворка, ваш выбор очевиден – это директива @apply
.
У вас есть кнопка
<button class="px-4 py-2 font-bold text-white bg-blue-500 rounded">Отправить</button>
И тут вам нужно использовать её где-то еще. Можно просто скопировать эту кнопку и вставить HTML-код в другое место. А можно открыть main.css
файл и скопировать TailwindCSS-классы туда в отдельный CSS-класс.
@tailwind base;
@tailwind components;
.btn {
@apply bg-blue-500 text-white font-bold py-2 px-4 rounded;
}
@tailwind utilities;
Теперь мы можем просто добавить btn
как обычный CSS-класс в HTML и переиспользовать сколько угодно раз. При этом мы можем как-угодно кастомизировать нашу кнопку, просто добавляя TailwindCSS-классы.
<button class="btn">Отправить</button>
<button class="btn px-6 py-4 bg-red-500">Отправить</button>
По-моему, такой подход смотрится значительно интереснее того же самого БЭМ. Мы пишем основные свойства кнопки, а все модификации пишем не в отдельный класс, а просто поверх.
Если же модифицированная кнопка используется не в одном месте, а в множестве, можно сделать модификатор. TailwindCSS вас в этом не ограничивает, но и не заставляет. При желании можно создать отдельный класс, и уже писать btn btn-red
. Подробнее в документации.
Если вы используете любой фронтенд-фреймворк, у вас вообще нет данной проблемы. Вам не нужна директива @apply
. Вы просто делаете отдельный компонент для любого повторяющегося кода. Легко и удобно.
Для примера воспользуемся самым простым из возможных вариантов – Alpine.js.
<div x-data="cards()" class="space-y-12">
<template x-for="card in cards">
<div>
<img class="rounded" :src="card.img" :alt="card.imgAlt" />
<div class="mt-2">
<div x-text="card.eyebrow" class="text-xs font-bold text-gray-600 uppercase"></div>
<div class="font-bold leading-snug text-gray-700">
<a x-text="card.title" :href="card.url" class="hover:underline"></a>
</div>
</div>
</div>
</template>
</div>
<script>
// ...
</script>
Даже если вы не планировали использовать фреймворк, 7 килобайт, которые вы потратите на Alpine.js, быстро окупятся. Подробнее об Alpine.js в других моих статьях.
А если вы вместо Alpine.js используете полноценный компонентный фреймворк (React, Vue и др.), это становится еще проще. Вы просто добавляете <MyComponent>
, где внутри скрыта вся логика.
4. Писать стили в HTML – это не плохо
Как ни крути, последнюю проблему невозможно решить. Потому что здесь это основная фича. Менять нужно не фреймворк, менять нужно отношение к нему.
Большую часть истории Web писать стили в HTML-коде было моветоном. Использовать тег style
было жутко неудобно, всё превращалось в жуткую колбасу, которую было невозможно разобрать. К тому же, некоторый новый функционал, например media-запросы (в TailwindCSS они есть как приставки sm:
, md:
), в нем просто не поддерживались. Отформатированный CSS был элементарно удобнее.
Когда появился Bootstrap, весь предыдущий негативный опыт отразился на отношении сообщества к такому подходу. И он сохранился до сих пор, хотя объективных причин для этого нет.
При правильной реализации, описывать стилизацию вместе с разметкой оказывается невероятно удобно. Удобно видеть HTML-элемент и сразу понимать, как он стилизован. Удобно писать верстку, не перескакивая из файла в файл. Если вы писали на Vue или на Svelte, вы знаете, о чем это я.
Заключение
Так какое же место занимает TailwindCSS в истории CSS?
Он удобнее ванильного CSS и не создает проблем со вложенностью и коллизией имен классов.
Он отлично работает со всеми препроцессорами. Поэтому, если вам нужно построить базу стилей с переменными, прогнать цикл и т.п., TailwindCSS этому никак не мешает.
TailwindCSS расширяет работу по БЭМ. Вам не нужно делать модификатор для каждого случая, просто сделайте базовый стиль и перезапишите сверху, что нужно. Если модифицированный блок используется не в одном месте, а в множестве, можно сделать модификатор. TailwindCSS вас в этом не ограничивает.
С TailwindCSS пограничные случаи не будут занимать отдельный класс. Можно вообще весь код писать без самописных классов. Так решается проблема, для которой были придуманы CSS-модули.
Мне нравится формат работы со стилями, который мне предлагает этот фреймворк. Но каждый должен попробовать и решить это для себя самого. Мне рекомендовали TailwindCSS со словами: "Попробуй, потом не захочешь делать по другому". Я попробовал, и теперь мне не хочется делать по другому. Попробуйте и вы.
Напоследок один небольшой лайфхак, который показывает еще одну удобную функцию TailwindCSS: с ним стили можно очень удобно править прямо в Chrome DevTools.
Выбираем элемент, в панели нажимаем.cls
, пишем классы, а затем просто копируем их к себе в верстку.
UPD: Для тех, кто еще сомневается, пару ссылок на дорожку про атомарный CSS: