Урок 14. Домашнее задание: оживить проект
⚡ Кратко
Добавить движение в проект курса: состояния кнопок, скелетоны загрузки,
появление уведомлений и одну собственную анимацию — с учётом
prefers-reduced-motion.
Задание
- все кнопки проекта получают
transition-colorsиactive:scale-95; - карточки списка слегка приподнимаются при наведении;
- страница со списком показывает скелетоны, пока «данные не загрузились»;
- уведомление появляется собственной анимацией из
@theme; - все анимации выключаются при
prefers-reduced-motion.
Подготовка окружения
cd tailwind-course
npm run dev
Пошаговое решение
Шаг 1. Кнопки
Добавьте transition-colors duration-150 и
active:scale-95. Проверьте, что фокус по-прежнему виден
и не анимируется — контур должен появляться мгновенно.
Шаг 2. Карточки
transition-all duration-200 hover:-translate-y-1 hover:shadow-lg.
На сенсорных устройствах эффект не сработает — это нормально, ничего
важного за ним быть не должно.
Шаг 3. Скелетоны
Сделайте компонент-заглушку, повторяющий геометрию карточки.
Показывайте его по флагу isLoading — данные пока можно
имитировать таймером.
Шаг 4. Своя анимация
📄 src/index.css
/* src/index.css */
@import "tailwindcss";
@theme {
--animate-fade-up: fade-up 0.25s ease-out;
}
@keyframes fade-up {
from { opacity: 0; transform: translateY(0.5rem); }
to { opacity: 1; transform: translateY(0); }
}
Примените motion-safe:animate-fade-up к уведомлению.
Как проверить
- Ни одна анимация не длится дольше 300 мс.
- При включённой настройке «уменьшить движение» интерфейс статичен.
- Скелетон совпадает по размерам с реальной карточкой — контент не «прыгает».
- В DevTools на вкладке Performance при наведении нет всплесков пересчёта раскладки.
Ориентир
<div class="max-w-md space-y-4">
<a href="#" class="group block rounded-xl border border-slate-200 bg-white p-4 transition-all duration-200 hover:-translate-y-1 hover:shadow-lg">
<div class="flex items-center justify-between">
<h3 class="text-sm font-semibold text-slate-900">Отчёт по продажам</h3>
<span class="text-slate-300 transition-transform group-hover:translate-x-1 group-hover:text-slate-500">→</span>
</div>
<p class="mt-1 text-sm text-slate-600">Наведите: карточка приподнимается.</p>
</a>
<div class="rounded-xl border border-slate-200 p-4">
<div class="h-3 w-1/2 animate-pulse rounded bg-slate-200"></div>
<div class="mt-2 h-3 animate-pulse rounded bg-slate-200"></div>
</div>
<div class="animate-fade-up rounded-lg border border-emerald-200 bg-emerald-50 p-3">
<p class="text-sm text-emerald-900">Уведомление с анимацией появления</p>
</div>
</div>