Tailwind CSS генерирует стили из utility-классов, которые реально встречаются в HTML и JavaScript проекта. Соберём первый экран, три карточки и мобильное меню через Vite-плагин Tailwind 4. Параллельно разберём responsive-префиксы, состояния hover и ловушку динамически склеенных имён классов.
Готовый лендинг легко скопировать как длинную строку классов и ничего не понять. Полезнее связывать каждый utility с конкретным layout-решением и проверкой на ширине 390 пикселей. В этой статье вы соберёте адаптивную страницу продукта с рабочей навигацией. Финальный результат можно проверить без догадок: desktop показывает горизонтальное меню и три карточки, mobile прячет ссылки за кнопкой, а Tab доходит до всех элементов.
Сначала семантические header, main, section и footer, потом классы.
Базовые utilities работают на mobile, md: меняет layout на широком экране.
Небольшой JavaScript переключает hidden и aria-expanded у меню.
Как Tailwind превращает классы в CSS
Vite читает index.html и main.js, плагин Tailwind сканирует исходники, а style.css импортирует tailwindcss. HTML остаётся семантическим, utilities задают layout, spacing, цвет и breakpoint. JavaScript отвечает только за открытие меню. Для Tailwind CSS держите этапы раздельно: ввод, проверка, основное действие и вывод. Такой маршрут позволяет остановиться в конкретной точке, увидеть фактические данные и исправить одну причину вместо случайной перестановки строк.
| Этап | Действие | Проверяемый результат |
|---|---|---|
| Сканирование | Tailwind находит статические class names | Нужные utilities попадают в CSS |
| Mobile base | Классы без префикса задают узкий экран | Страница читается на 390 px |
| Breakpoint | md: меняет grid и navigation | Desktop использует свободное место |
| Interaction | Click меняет hidden и aria-expanded | Меню управляется кнопкой |
Mobile-first означает, что базовый класс не является desktop-версией, а описывает самый узкий сценарий. У Tailwind CSS каждый этап оставляет наблюдаемый след, поэтому следующий шаг начинается только после проверки предыдущего.

От входных данных до видимого результата. Scanner видит полные имена utilities
Собираем hero, карточки и меню
Создайте vanilla Vite-проект, установите npm install tailwindcss @tailwindcss/vite, добавьте tailwindcss() в vite.config.js и строку @import "tailwindcss"; в src/style.css. Это актуальная схема Tailwind 4 с Vite-плагином. Старые инструкции с обязательным tailwind.config.js и autoprefixer относятся к другой версии.
<header class="border-b border-slate-200 bg-white">
<nav class="mx-auto flex max-w-6xl items-center justify-between p-4">
<a class="font-black text-slate-950" href="#">FocusLab</a>
<button id="menu-button"
class="rounded-lg border px-3 py-2 md:hidden"
aria-expanded="false" aria-controls="menu">
Menu
</button>
<div id="menu" class="hidden gap-6 md:flex">
<a class="hover:text-cyan-700" href="#features">Features</a>
<a class="hover:text-cyan-700" href="#start">Start</a>
</div>
</nav>
</header>
<main>
<section class="mx-auto grid max-w-6xl gap-10 px-4 py-16 md:grid-cols-2">
<div>
<p class="font-bold text-cyan-700">Small steps, visible progress</p>
<h1 class="mt-3 text-4xl font-black text-slate-950 md:text-6xl">
Build a calmer study routine
</h1>
<p class="mt-5 text-lg text-slate-600">
One focus block, one result, one clear next action.
</p>
<a class="mt-8 inline-block rounded-xl bg-cyan-600 px-5 py-3 font-bold text-white hover:bg-cyan-700 focus:outline-2 focus:outline-offset-4"
href="#start">Try the timer</a>
</div>
<div class="rounded-3xl bg-slate-950 p-8 text-white">25:00</div>
</section>
<section id="features" class="mx-auto grid max-w-6xl gap-4 px-4 pb-16 md:grid-cols-3">
<article class="rounded-2xl border p-6"><h2 class="font-bold">Plan</h2><p>Choose one task.</p></article>
<article class="rounded-2xl border p-6"><h2 class="font-bold">Focus</h2><p>Protect one block.</p></article>
<article class="rounded-2xl border p-6"><h2 class="font-bold">Review</h2><p>Write the result.</p></article>
</section>
</main>- На mobile hero и карточки стоят в одну колонку.
- С md: hero делится на две колонки, features на три.
- Кнопка меню видна только до md breakpoint.
- Focus outline остаётся заметным для клавиатуры.
Utilities сгруппированы по смыслу внутри реальных блоков: layout, spacing, typography и state. Классы не заменяют семантические теги. Пример Tailwind CSS специально ограничен одним пользовательским сценарием, чтобы назначение каждой строки оставалось видимым.

Что отличает устойчивый проект от случайного запуска. Mobile-first остаётся основой
Как читать responsive и state utilities
Tailwind сканирует исходники как текст и генерирует только обнаруженные utility-классы. Responsive variant md: оборачивает правило в media query. hover: и focus: создают селекторы состояния. Классы применяются слева направо не как обычный inline-style: порядок CSS определяет сам генератор. Конфликтующие utilities лучше не оставлять одновременно. Для произвольного значения есть синтаксис в квадратных скобках, но частое его использование разрушает общий ритм системы.
| Часть | За что отвечает | Что проверить |
|---|---|---|
| Vite plugin | Подключает Tailwind к build | Плагин есть в config |
| @import | Добавляет generated CSS | style.css импортирован |
| Base classes | Описывают mobile | Читаемо на 390 px |
| md variant | Меняет layout | Desktop не ломает mobile |
| ARIA | Описывает состояние menu | expanded синхронизирован |
Повторяющаяся карточка не обязательно требует @apply: во фреймворке лучше вынести компонент, который печатает одинаковый набор классов. Для простого HTML можно создать небольшой CSS-компонент, но не превращайте utilities обратно в сотни придуманных классов. Проверяйте контраст: cyan-600 с белым текстом отличается от декоративного cyan-300.
Проверяем mobile, focus и production build
Соберите страницу и уменьшите окно до 390 пикселей. Добавьте JavaScript для menu-button: переключайте hidden и aria-expanded. Пройдите страницу клавишей Tab. Увеличьте текст в браузере до 200 процентов. Добавьте четвёртую карточку и решите, нужна ли сетка md:grid-cols-2 xl:grid-cols-4. Запустите npm run build и npm run preview. Затем удалите случайный utility и убедитесь, что production меняется ожидаемо.
- Проверьте mobile в одну колонку.
- Откройте и закройте menu.
- Пройдите ссылки клавишей Tab.
- Увеличьте zoom до 200%.
- Добавьте четвёртую карточку.
- Проверьте production preview.
- Layout mobile-first.
- Menu доступно с клавиатуры.
- Классы статичны и сканируются.
- Build совпадает с dev.
Сочный лендинг получается не из количества utilities, а из устойчивой структуры, ограниченной палитры и проверенных состояний. После этой проверки измените одно правило Tailwind CSS и заранее запишите ожидаемый результат. Так копирование превращается в понимание.

Четыре проверки перед следующим шагом. Accessibility проверяется вместе с видом
Когда выносить повторения в компоненты
Дальше вынесите повторяющиеся секции в компоненты выбранного фреймворка, добавьте реальные данные и форму с server-side проверкой. Настройте токены темы, если проекту нужны свои цвета. Для dark mode сначала определите контраст всех поверхностей. Не копируйте компонент целиком из неизвестной библиотеки без проверки лицензии и accessibility. Производительность измеряйте production build, а изображения оптимизируйте отдельно от CSS.
Как изучить тему в Кодике
Закрепите семантический HTML, Flexbox, Grid и media queries, затем сопоставьте их с utilities. В Кодике сначала восстановите чистую логику без фреймворка, затем верните библиотеку и интерфейс Tailwind CSS.
| Шаг | Что разобрать | Мини-проверка |
|---|---|---|
| 1 | HTML-секции | Собрать header и main |
| 2 | Flex и Grid | Разложить hero и cards |
| 3 | Media queries | Объяснить md: |
| 4 | Состояния | Добавить hover и focus |
| 5 | JavaScript menu | Синхронизировать aria-expanded |
Если вы понимаете CSS-свойство за utility, Tailwind ускоряет работу и не скрывает основу. Финальная проверка для Tailwind CSS: закрыть статью, объяснить путь данных и добавить одну функцию без копирования готового блока.
Для Tailwind 4 и Vite используйте официальный @tailwindcss/vite.
Храните полные варианты, чтобы scanner их увидел.
Заменяйте его заметным focus-стилем, а не удаляйте.
Стройте базовые classes для mobile и тестируйте узкую ширину.
Что получится в итоге

Hero, карточки и навигация меняют layout по breakpoint, а мобильное меню остаётся доступным и предсказуемым.
Как Tailwind CSS узнаёт, какие стили генерировать?
Tailwind сканирует исходники на полные имена utility-классов и включает найденные правила в CSS.
Что означает префикс md: в Tailwind?
md: применяет utility начиная с соответствующего breakpoint, а базовый класс остаётся mobile-first.
Почему bg-${color}-500 опасен?
Динамически склеенное имя может отсутствовать как полный текст и не попасть в сгенерированный CSS.
Как понять, что учебный проект Tailwind CSS действительно работает?
Проверьте основной сценарий Tailwind CSS, неверный ввод, повторный запуск и один граничный случай. Затем объясните путь данных своими словами.
Можно ли начать с готового кода Tailwind CSS из статьи?
Да. Сначала добейтесь результата Tailwind CSS, затем измените одно правило и восстановите ключевой файл без копирования.
Основы закрепите в курсе HTML и курсе CSS, поведение меню в курсе JavaScript.
Сравните структуру с портфолио программиста, меню с burger menu и палитру с тёмной темой сайта.