🔘 Кнопки

Варианты, размеры, состояния и группы

Варианты по важности

На экране одна основная кнопка. Всё остальное — вторичные варианты.

<div class="flex flex-wrap items-center gap-3">
  <button class="rounded-md bg-slate-900 px-4 py-2 text-sm font-medium text-white transition-colors 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 bg-white px-4 py-2 text-sm font-medium text-slate-700 transition-colors
                 hover:bg-slate-50 dark:border-slate-600 dark:bg-transparent dark:text-slate-200 dark:hover:bg-slate-800">Вторичная</button>
  <button class="rounded-md px-4 py-2 text-sm font-medium text-slate-600 transition-colors hover:bg-slate-100
                 dark:text-slate-300 dark:hover:bg-slate-800">Призрачная</button>
  <button class="rounded-md bg-rose-600 px-4 py-2 text-sm font-medium text-white transition-colors hover:bg-rose-700">Опасная</button>
  <button class="text-sm font-medium text-sky-700 underline-offset-4 hover:underline dark:text-sky-400">Ссылка</button>
</div>

Размеры

У кнопки-иконки обязателен aria-label — иначе её нечем назвать.

<div class="flex flex-wrap items-center gap-3">
  <button class="rounded-md bg-slate-900 px-2.5 py-1 text-xs font-medium text-white">Маленькая</button>
  <button class="rounded-md bg-slate-900 px-3 py-1.5 text-sm font-medium text-white">Средняя</button>
  <button class="rounded-md bg-slate-900 px-5 py-2.5 text-base font-medium text-white">Большая</button>
  <button class="rounded-md bg-slate-900 p-2 text-white" aria-label="Настройки">⚙</button>
</div>

С иконкой и состоянием загрузки

shrink-0 у иконки не даёт ей сплющиться при длинной подписи.

<div class="flex flex-wrap items-center gap-3">
  <button class="inline-flex items-center gap-2 rounded-md bg-slate-900 px-3 py-2 text-sm font-medium text-white">
    <svg class="size-4 shrink-0" viewBox="0 0 20 20" fill="none" aria-hidden="true"><path d="M10 4v12M4 10h12" stroke="currentColor" stroke-width="2" stroke-linecap="round"/></svg>
    Добавить
  </button>
  <button class="inline-flex cursor-not-allowed items-center gap-2 rounded-md bg-slate-900/70 px-3 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>
  <button class="inline-flex items-center gap-2 rounded-md bg-slate-200 px-3 py-2 text-sm font-medium text-slate-500" disabled>Недоступно</button>
</div>

Группа кнопок

Скругление задаётся контейнеру, а overflow-hidden обрезает внутренние кнопки по форме.

<div class="inline-flex overflow-hidden rounded-md border border-slate-300 dark:border-slate-600">
  <button class="bg-slate-900 px-3 py-1.5 text-sm font-medium text-white">День</button>
  <button class="border-l 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>
  <button class="border-l 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>

Кнопка во всю ширину на мобильном

w-full sm:w-auto — стандартный приём для форм и модальных окон.

<div class="max-w-sm">
  <button class="w-full rounded-md bg-slate-900 px-4 py-2.5 text-sm font-medium text-white sm:w-auto">
    Оформить заказ
  </button>
</div>

Разбор

КлассЗачем
inline-flex items-center gap-2иконка и текст в одну строку и по центру
px-4 py-2по горизонтали больше, чем по вертикали — так кнопка выглядит устойчиво
rounded-mdрадиус кнопки обычно меньше радиуса карточки
text-sm font-mediumподпись немного плотнее обычного текста
transition-colorsплавная смена фона — 150 мс
hover: + focus-visible:состояния для мыши и клавиатуры
disabled:opacity-50выключенное состояние
active:scale-95тактильный отклик при нажатии

Вариант на shadcn/ui

<Button>Основная</Button>
<Button variant="outline">Вторичная</Button>
<Button variant="ghost" size="sm">Призрачная</Button>
<Button variant="destructive">Удалить</Button>
<Button size="icon" aria-label="Настройки"><SettingsIcon /></Button>
<Button disabled>Недоступно</Button>

Частые ошибки

  • Несколько «основных» кнопок на одном экране — непонятно, что делать.
  • Кнопка-иконка без aria-label.
  • outline-none без замены — интерфейс непроходим с клавиатуры.
  • Кнопка вместо ссылки для перехода: ломается средний клик и «открыть в новой вкладке».
  • Подпись «Да» вместо действия: правильнее «Удалить проект».
  • Слишком маленькая зона нажатия на мобильных — держите минимум 40px по высоте.