Урок 10. Домашнее задание: каталог с липкой панелью

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

⚡ Кратко

Собрать список товаров: карточки с метками в углу, липкая панель фильтров сверху и корзина, зафиксированная в углу экрана.

Задание

В проекте курса сделайте страницу каталога:

  • липкая панель фильтров: прилипает к верху при прокрутке, полупрозрачный фон;
  • сетка карточек; у части товаров — метка «Хит» или «−30%» в углу;
  • кнопка корзины, зафиксированная в правом нижнем углу окна;
  • у каждой карточки при наведении появляется кнопка «Быстрый просмотр»;
  • слои расставлены по шкале: панель 10, всплывающее 20, фиксированная кнопка 30.

Подготовка окружения

cd tailwind-course
npm run dev

Пошаговое решение

Шаг 1. Панель фильтров

sticky top-0 z-10 border-b border-slate-200 bg-white/90 px-4 py-3. Полупрозрачный фон делает переход мягче, но текст под панелью просвечивать не должен — держите непрозрачность не ниже 90%.

Шаг 2. Карточка с меткой

Карточке — relative overflow-hidden, метке — absolute top-3 left-3 z-10. Проверьте, что метка не обрезается скруглением.

Шаг 3. Кнопка при наведении

Карточке добавьте group, кнопке — absolute inset-x-3 bottom-3 opacity-0 transition-opacity group-hover:opacity-100. Подробнее про group — урок 12.

Шаг 4. Фиксированная корзина

fixed right-6 bottom-6 z-30. Убедитесь, что кнопка не перекрывает важный контент на мобильных — при необходимости уменьшите её на маленьких экранах.

Как проверить

  • При прокрутке панель фильтров остаётся видимой, контент под ней не просвечивает.
  • Метки не обрезаются и не «уезжают» при изменении размера окна.
  • Кнопка корзины видна всегда и не мешает нажимать карточки.
  • В коде нет z-index больше 50.

Ориентир

−30%

Товар А

Хит

Товар Б

<div class="relative h-64 overflow-y-auto rounded-xl border border-slate-200 bg-slate-50">
  <div class="sticky top-0 z-10 flex items-center gap-2 border-b border-slate-200 bg-white/95 px-4 py-2">
    <button class="rounded-full bg-slate-900 px-3 py-1 text-xs text-white">Все</button>
    <button class="rounded-full border border-slate-300 px-3 py-1 text-xs text-slate-700">Новинки</button>
    <button class="rounded-full border border-slate-300 px-3 py-1 text-xs text-slate-700">Скидки</button>
  </div>
  <div class="grid grid-cols-2 gap-3 p-3">
    <div class="group relative overflow-hidden rounded-lg border border-slate-200 bg-white">
      <span class="absolute top-2 left-2 z-10 rounded-full bg-rose-600 px-2 py-0.5 text-[10px] font-semibold text-white">−30%</span>
      <div class="h-20 bg-slate-100"></div>
      <div class="p-3"><p class="text-sm font-medium text-slate-900">Товар А</p></div>
      <button class="absolute inset-x-3 bottom-3 rounded-md bg-slate-900 py-1.5 text-xs text-white opacity-0 transition-opacity group-hover:opacity-100">Быстрый просмотр</button>
    </div>
    <div class="group relative overflow-hidden rounded-lg border border-slate-200 bg-white">
      <span class="absolute top-2 left-2 z-10 rounded-full bg-emerald-600 px-2 py-0.5 text-[10px] font-semibold text-white">Хит</span>
      <div class="h-20 bg-slate-100"></div>
      <div class="p-3"><p class="text-sm font-medium text-slate-900">Товар Б</p></div>
      <button class="absolute inset-x-3 bottom-3 rounded-md bg-slate-900 py-1.5 text-xs text-white opacity-0 transition-opacity group-hover:opacity-100">Быстрый просмотр</button>
    </div>
    <div class="h-24 rounded-lg border border-slate-200 bg-white"></div>
    <div class="h-24 rounded-lg border border-slate-200 bg-white"></div>
  </div>
  <button class="absolute right-4 bottom-4 z-30 rounded-full bg-slate-900 px-4 py-2 text-sm font-medium text-white shadow-lg">Корзина · 2</button>
</div>

В демонстрации использован absolute вместо fixed, чтобы кнопка не «улетела» за пределы примера. В вашем проекте это будет fixed right-6 bottom-6.