🗂️ Карточка
Базовая карточка
Рамка или тень — что-то одно. Рамка лучше держит ритм в длинных списках.
Отчёт за июль
Данные обновлены пять минут назад. Выгрузка доступна в CSV и PDF.
<div class="max-w-sm rounded-xl border border-slate-200 bg-white p-5 dark:border-slate-700 dark:bg-slate-900">
<h3 class="text-base font-semibold text-slate-900 dark:text-slate-50">Отчёт за июль</h3>
<p class="mt-1 text-sm text-slate-600 dark:text-slate-400">
Данные обновлены пять минут назад. Выгрузка доступна в CSV и PDF.
</p>
<div class="mt-4 flex gap-2">
<button class="rounded-md bg-slate-900 px-3 py-1.5 text-sm font-medium text-white hover:bg-slate-700
dark:bg-slate-100 dark:text-slate-900 dark:hover:bg-white">Открыть</button>
<button class="rounded-md border border-slate-300 px-3 py-1.5 text-sm font-medium text-slate-700
hover:bg-slate-50 dark:border-slate-600 dark:text-slate-200 dark:hover:bg-slate-800">Скачать</button>
</div>
</div>
Карточка с медиа
Обязателен overflow-hidden у контейнера — иначе медиа-блок вылезет за скругление.
Аналитика
Как читать воронку
Разбираем метрики и типичные ошибки интерпретации.
<div class="max-w-sm overflow-hidden rounded-xl border border-slate-200 bg-white dark:border-slate-700 dark:bg-slate-900">
<div class="h-32 bg-linear-to-br from-sky-400 to-indigo-500"></div>
<div class="p-5">
<span class="text-xs font-semibold uppercase tracking-widest text-sky-700 dark:text-sky-400">Аналитика</span>
<h3 class="mt-1 text-base font-semibold text-slate-900 dark:text-slate-50">Как читать воронку</h3>
<p class="mt-1 text-sm text-slate-600 dark:text-slate-400">Разбираем метрики и типичные ошибки интерпретации.</p>
</div>
</div>
Кликабельная карточка
Вся карточка — одна ссылка. Так не бывает «мёртвых зон», и элемент один раз попадает в обход клавиатурой.
<a href="#" class="group block max-w-sm rounded-xl border border-slate-200 bg-white p-5 transition-all
hover:-translate-y-0.5 hover:border-slate-300 hover:shadow-lg
focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-sky-600
dark:border-slate-700 dark:bg-slate-900 dark:hover:border-slate-600">
<div class="flex items-start justify-between gap-3">
<div>
<h3 class="text-base font-semibold text-slate-900 dark:text-slate-50">Настройки команды</h3>
<p class="mt-1 text-sm text-slate-600 dark:text-slate-400">Роли, доступы и приглашения</p>
</div>
<span class="text-slate-300 transition-transform group-hover:translate-x-1 group-hover:text-slate-500">→</span>
</div>
</a>
Карточка-метрика
Числа — tabular-nums, иначе при обновлении данных колонка «пляшет».
Выручка
1,24 млн
▲ 12%Возвраты
12
▲ 3<div class="grid gap-3 sm:grid-cols-2">
<div class="rounded-xl border border-slate-200 bg-white p-4 dark:border-slate-700 dark:bg-slate-900">
<p class="text-xs text-slate-500 dark:text-slate-400">Выручка</p>
<p class="mt-1 text-2xl font-semibold tabular-nums text-slate-900 dark:text-slate-50">1,24 млн</p>
<span class="mt-2 inline-flex rounded-full bg-emerald-500/15 px-2 py-0.5 text-xs font-medium text-emerald-700 dark:text-emerald-300">▲ 12%</span>
</div>
<div class="rounded-xl border border-slate-200 bg-white p-4 dark:border-slate-700 dark:bg-slate-900">
<p class="text-xs text-slate-500 dark:text-slate-400">Возвраты</p>
<p class="mt-1 text-2xl font-semibold tabular-nums text-slate-900 dark:text-slate-50">12</p>
<span class="mt-2 inline-flex rounded-full bg-rose-500/15 px-2 py-0.5 text-xs font-medium text-rose-700 dark:text-rose-300">▲ 3</span>
</div>
</div>
Состояние загрузки
Скелетон повторяет геометрию настоящей карточки — тогда при появлении данных ничего не «прыгает».
<div class="max-w-sm rounded-xl border border-slate-200 bg-white p-5 dark:border-slate-700 dark:bg-slate-900">
<div class="h-4 w-1/3 animate-pulse rounded bg-slate-200 dark:bg-slate-700"></div>
<div class="mt-3 h-3 animate-pulse rounded bg-slate-200 dark:bg-slate-700"></div>
<div class="mt-2 h-3 w-4/5 animate-pulse rounded bg-slate-200 dark:bg-slate-700"></div>
<div class="mt-4 h-8 w-24 animate-pulse rounded-md bg-slate-200 dark:bg-slate-700"></div>
</div>
Разбор
| Класс | Зачем |
|---|---|
rounded-xl | скругление карточки; вложенным элементам ставят меньший радиус |
border border-slate-200 | рамка: толщина и цвет — всегда два класса |
bg-white dark:bg-slate-900 | поверхность в обеих темах |
p-5 | внутренний отступ 20px — комфортный минимум для карточки |
overflow-hidden | обязателен, если внутри есть медиа или цветная шапка |
group + group-hover: | реакция вложенных элементов на наведение |
focus-visible:outline-2 | видимый фокус для кликабельной карточки |
Вариант на shadcn/ui
<Card>
<CardHeader>
<CardTitle>Отчёт за июль</CardTitle>
<CardDescription>Данные обновлены пять минут назад</CardDescription>
</CardHeader>
<CardContent>…</CardContent>
<CardFooter className="justify-end gap-2">
<Button variant="ghost">Скачать</Button>
<Button>Открыть</Button>
</CardFooter>
</Card>
Частые ошибки
- Рамка и крупная тень одновременно — они спорят друг с другом.
- Забытый
overflow-hidden: картинка вылезает за скруглённые углы. - Радиус вложенного элемента больше, чем у карточки — выглядит неаккуратно.
- Кликабельная карточка сделана на
divс обработчиком: не работает клавиатура. - Внутри карточки-ссылки ещё одна ссылка или кнопка — вложенные интерактивные элементы недопустимы.