Урок 14. Примеры: живые элементы

📁 Раздел: Состояния и темы ⏱️ Время изучения: ~45 мин 🎯 Сложность: Средняя

⚡ Кратко

Шесть примеров: кнопка, карточка, скелетон, кнопка загрузки, аккордеон и уведомление. Все — наводите курсор.

1. Кнопка с полным набором

<button class="rounded-md bg-slate-900 px-4 py-2 text-sm font-medium text-white
               transition-all duration-150 hover:bg-slate-700 active:scale-95
               focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-slate-900">
  Нажмите меня
</button>

active:scale-95 даёт ощущение физического нажатия — мелочь, которую замечают все.

2. Карточка, которая «поднимается»

<a href="#" class="group block max-w-sm rounded-xl border border-slate-200 bg-white p-5
                   transition-all duration-200 hover:-translate-y-1 hover:shadow-lg">
  <h3 class="text-sm font-semibold text-slate-900">Отчёт за квартал</h3>
  <p class="mt-1 text-sm text-slate-600">Наведите — карточка приподнимется.</p>
  <span class="mt-3 inline-flex items-center gap-1 text-sm text-sky-700">
    Открыть <span class="transition-transform group-hover:translate-x-1">→</span>
  </span>
</a>

3. Скелетон загрузки

<div class="max-w-sm space-y-3 rounded-xl border border-slate-200 p-4">
  <div class="flex items-center gap-3">
    <div class="size-10 animate-pulse rounded-full bg-slate-200"></div>
    <div class="flex-1 space-y-2">
      <div class="h-3 w-1/2 animate-pulse rounded bg-slate-200"></div>
      <div class="h-3 w-1/3 animate-pulse rounded bg-slate-200"></div>
    </div>
  </div>
  <div class="h-3 animate-pulse rounded bg-slate-200"></div>
  <div class="h-3 w-4/5 animate-pulse rounded bg-slate-200"></div>
</div>

Скелетон честнее спиннера: он показывает будущую структуру и уменьшает ощущение ожидания.

4. Кнопка в состоянии загрузки

<div class="flex flex-wrap gap-3">
  <button class="inline-flex items-center gap-2 rounded-md bg-sky-600 px-4 py-2 text-sm font-medium text-white">
    Сохранить
  </button>
  <button class="inline-flex cursor-not-allowed items-center gap-2 rounded-md bg-sky-600/70 px-4 py-2 text-sm font-medium text-white" disabled>
    <span class="size-4 animate-spin rounded-full border-2 border-white/40 border-t-white"></span>
    Сохраняем…
  </button>
</div>

5. Аккордеон с поворотом стрелки

Подробности заказа ▾

Стрелка поворачивается за 200 мс — ровно столько, чтобы движение заметили, но не ждали.

<details class="group max-w-md rounded-lg border border-slate-200 bg-white p-4">
  <summary class="flex cursor-pointer list-none items-center justify-between text-sm font-medium text-slate-900">
    Подробности заказа
    <span class="text-slate-400 transition-transform duration-200 group-open:rotate-180">▾</span>
  </summary>
  <p class="mt-3 text-sm text-slate-600">Стрелка поворачивается за 200 мс — ровно столько, чтобы движение заметили, но не ждали.</p>
</details>

6. Уведомление с появлением

Изменения сохранены

Появилось с собственной анимацией fade-up.

<div class="max-w-sm animate-fade-up rounded-lg border border-emerald-200 bg-emerald-50 p-4">
  <p class="text-sm font-medium text-emerald-900">Изменения сохранены</p>
  <p class="mt-1 text-xs text-emerald-800">Появилось с собственной анимацией fade-up.</p>
</div>
/* 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); }
}

7. Уважение к настройке движения

↓

Стрелка прыгает только у тех, кто не отключал анимации в системе.

<div class="flex items-center gap-4">
  <span class="text-2xl motion-safe:animate-bounce">↓</span>
  <p class="text-sm text-slate-600">
    Стрелка прыгает только у тех, кто не отключал анимации в системе.
  </p>
</div>