Культ HTMX + daisyUI
После того как мы кратко познакомились с htmx и всё таки решили пойти в крестовый поход против javascript, vite, react, ангуляра и здравого смысла, пора задуматься какие же задачи мы можем решить с помощью htmx а какие - нет.
Htmx решает одну задачу: обновляет определенную часть интерфейса куском HTML который вернул сервер. Можно настраивать когда обновлять, что именно менять и как это встраивать в DOM, но суть именно такая. Сам по себе htmx никак не отвечает за стили и не диктует, как оформлять интерфейс. Этот вопрос я предлагаю закрывать через… daisyUI!
daisyUI - слой поверх tailwind который даёт готовые классы-компоненты. Честно, уважаемые читатели, я пробовал довольно много решений которые должны “просто работать”:
- Вайбкодить весь сырой css без какой-либо библиотеки - оказалось что тут не всё так просто и задачки занимали ОЧЕНЬ много времени даже простые даже если как-то структурировать css. И много токенов уходило на “поддержку” этих стилей
- Вайбкодить весь сырой css с помощью “очистителей” то есть чтото типа a-more-modern-css-reset - разницы с первым пунктом особо не заметил.
- CSS first библиотеки а-ля “picocss”, решения в которых весь css написан за тебя то есть твой </button> выглядит уже совсем не как дефолтный. У LLMок, по моему опыту, начинаются трудности поскольку бОльшая часть css находится вне проекта и, соответственно, вне контекста.
- Tailwind CDN - честно, я практически переставал понимать десятки классов которые клод пихал в атрибуты… это тоже становилось довольно тяжело
Напомню что я преследовал оч конкретную цель - вайбкодинг фронта для:
- админок
- внутренних панелей
- MVP
И вот тут я пришёл к daisyUI! Это заранее написанные и сгруппированные tailwind классы, на нашей стороне количество стилей ну МИНИМАЛЬНО. На актуальном daisyUI v5 это выглядит примерно так.
Чистый Tailwind:
<div class="rounded-lg border border-gray-200 bg-white p-6 shadow-sm">
<h2 class="text-xl font-semibold text-gray-900">Delete post</h2>
<p class="mt-2 text-sm text-gray-500">
This action is irreversible.
</p>
<div class="mt-4 flex justify-end gap-2">
<button class="inline-flex h-10 items-center justify-center rounded-md border border-gray-200 px-4 text-sm font-medium transition hover:bg-gray-100">
Cancel
</button>
<button class="inline-flex h-10 items-center justify-center rounded-md bg-red-600 px-4 text-sm font-medium text-white transition hover:opacity-90">
Delete
</button>
</div>
</div>
daisyUI:
<div class="card bg-base-100 shadow-sm border border-base-300">
<div class="card-body">
<h2 class="card-title">Delete post</h2>
<p>This action is irreversible.</p>
<div class="card-actions justify-end">
<button class="btn">Cancel</button>
<button class="btn btn-error">Delete</button>
</div>
</div>
</div>
Для моего юзкейса это важно не потому, что daisyUI какой-то “магический фреймворк красоты”, а потому что он снижает LOC и снижает шансы что LLMка случайно сгенерит свалку из десятков 27 utility-классов половину из которых потом забудет. Сами авторы daisyUI поддерживают актуальную LLM-first документацию где чё использовать!
Честно, даже не хочется расписывать особо технические плюсы минусы. Я не фронтендер и сам эти стили не читаю… Самое главное МНЕ что такое решение просто работает и позволяет не тратить большое кол-во токенов на поддержку этого чудища. Если замечаю что становится подозрительно много стилей промчу что-то вроде “изучи доку daisyUI и подумай не нарушаем ли мы базовые принципы”. Кода стилей становится существенно меньше)0))
Давайте поговорим про ощутимые минусы. Всё вот это “удобно, zero-build, кайф” очень отрезвляется ситуацией в которой кто-то заходит на сайтик и видит какую-то сломанную дичь… Почему? Потому что HTML у нас может приехать нормально с нашего сервера, а вот CSS едет отдельным запросом на внешний CDN.
Типичный zero-build кусок выглядит так:
<link
href="https://cdn.jsdelivr.net/npm/daisyui@5"
rel="stylesheet"
type="text/css"
/>
<script src="https://cdn.jsdelivr.net/npm/@tailwindcss/browser@4"></script>
То есть страница открывается не одним монолитным “сайт загрузился”, а цепочкой:
- браузер получает HTML
- видит ссылку на внешний стайлщит
- идет в другой домен за CSS
- ждет пока тот ответит
- только потом нормально красит интерфейс
И вот этот внешний CDN может тупить, быть временно недоступен. У пользователя может резаться доступ корпоративной сетью, адблоком, провайдером, чем угодно(( Причём с @tailwindcss/browser ситуация сложнее чем с обычным CSS: это не файл со стилями, а JS который сканирует DOM и генерирует CSS прямо браузере — значит даже при доступном CDN стили могут не применится если скрипт упал, не успел отработать до рендера, или ещё чего. Такое происходит(
В этот момент пользователь видит что кнопки расползлись, карточки исчезли, отступы умерли, интерфейс ВСЁ
Чисто технически можно попробовать:
- Вшивать css себе в свой бэк т.е в свою static директорию.
- Плюсы: независимость от внешнего CDN, полный контроль над тем что и откуда грузится, LLMке проще работать с локальным файлом
- Минусы: начинаешь сам отвечать за доставку, кеширование и обновление этих стилей
- Добавить немного JS который прячет
bodyдо загрузки CDN и показывает обратно поonload/onerror, плюс таймаут на случай зависания:<style>body { visibility: hidden }</style> <script src="https://cdn.jsdelivr.net/npm/@tailwindcss/browser@4" onload="document.body.style.visibility=''" onerror="document.body.style.visibility=''"> </script> <script>setTimeout(() => document.body.style.visibility = '', 3000)</script>- Плюсы: пользователь не видит сломанный интерфейс, только пустую страницу на момент загрузки
- Минусы: если CDN совсем умер — 3 секунды белого экрана перед тем как таймаут сработает
- Реально собирать css с помощью (условно) ноды отдельным процессом
- Получится уже не чистый zero-build, зато это самый взрослый вариант если проект ВДРУГ вырос
Я ничего этого не использовал потому что нет необходимости эти проблемы решать, я перезагружу страничку итд. Всё работает четко в 90% случаев ну и конкретно для моего юзкейса этого достаточно.
Обязательно попробую какие-то решения выше и отпишу… Вообщем, использовать htmx вместе с daisyUI это некая БАЗА из моего практического опыта