Кнопки: компонент
Как строить компонент кнопки: button/a, состояния, доступность, варианты размера/цвета и повышение качества клик-поверхности.
1. Кнопка или ссылка?
button — действие (отправить, открыть, получить), a — переход (страница, якорь). Правильный выбор — первый шаг доступности и солидности кода.
| Хочу | Элемент |
|---|---|
| Действие в странице | button |
| Перейти на страницу/якорь | a href |
| Форма: отправить/сброс | button type=submit/reset |
| Одностр. навигация | a с href |
<button type="button">Открыть меню</button>
<form>
<button type="submit">Отправить</button>
<button type="reset">Очистить</button>
</form>
<a class="btn" href="/catalog">В каталог</a>2. Состояния и сменность
.btn { background:#2563eb; color:#fff; border:none; border-radius:8px;
padding:10px 18px; font:inherit; cursor:pointer; }
.btn:hover { background:#1d4ed8; }
.btn:focus-visible { outline:3px solid #93c5fd; outline-offset:2px; }
.btn:active { transform: translateY(1px); }
.btn:disabled { opacity:.5; cursor:not-allowed; }hover, focus-visible, active, disabled — обязательный набор. focus-visible: кольцо видно при клавиатуре и «умно» исчезает на тач.
3. Варианты
.btn--primary { background:#2563eb; }
.btn--ghost { background:transparent; border:1px solid #2563eb; color:#2563eb; }
.btn--link { background:none; color:#2563eb; padding:0; text-decoration:underline; }
.btn--danger { background:#dc2626; }
.btn--lg { padding:14px 24px; font-size:1.1rem; }
.btn--sm { padding:6px 12px; font-size:.875rem; }4. Стилизация ссылки-кнопки
Если нужен «кнопочный» вид у ссылки — тот же класс btn. Но смена: для a не пишут disabled (не сработает) — вместо него aria-disabled="true" и style pointer-events.
.btn { display:inline-block; text-decoration:none; }
<a class="btn" href="/pay" aria-disabled="true">Оплатить</a>5. Доступность
- текст кнопки понятен без контекста: «Отправить отзыв», не «Ок»;
- иконка без текста — aria-label;
- фокус видим — focus-visible;
- контраст текста/фона ≥ 4.5:1.
<button aria-label="Корзина, 2 товара">
<svg aria-hidden="true">…</svg>
</button>6. Клик-поверхность
.btn--lg, .nav__link { min-height: 44px; display:inline-flex; align-items:center; }guideline: цель для пальца ≥ 44×44 пикселей. Простая выручалка — min-height у кнопок и ссылок меню; или минмиодый свиток: padding следует подставить.
7. Загрузка и невозможность двойных кликов
Кнопки оплаты/отправки: disable после первого клика или inline-spinner. Используйте aria-busy="true" на кнопке.
<button type="submit" aria-busy="true">Отправка…</button>8. Анимации и микро-взаимодействия
.btn { transition: background .15s ease, transform .15s ease; }
.btn:active { transform: translateY(1px); }Скорость перехода 120–200 мс — живое ощущение. Не переыгывая с transform на position — дёшево и плавно. Уважайте prefers-reduced-motion.
9. Чек-лист кнопок
- правильный элемент (button/a);
- состояния hover/focus/active/disabled;
- варианты по смыслу: primary/ghost/danger;
- цель 44px, контраст ок;
- защита от двойного сабмита;
- микро-анимации с transition;
- reduced-motion — уважаем.
Что дальше
Курс завершён.