Выбор контролов: чекбокс, свитч, радиокнопка
1) Ключевые различия (смысл, не «рисунок»)
Правило:- Нужен один из N — берите радио.
- Нужен любой набор флагов — чекбоксы.
- Нужен один бинарный тумблер, который сразу меняет поведение — свитч.
2) Дерево решений (коротко)
1. Несколько независимых выборов? → Чекбоксы.
2. Ровно один вариант из набора? → Радиокнопки (или сегмент-контрол/тэглы).
3. Один бинарный флаг, эффект мгновенный и заметный? → Свитч.
4. Нужна «частичная» отметка (подмножество)? → Чекбокс с tri-state.
5. Риск/стоимость высоки (платеж, модерация)? → Радио/чекбокс + подтверждение (не свитч).
3) Поведение и ожидания пользователя
Свитч = моментальный результат. После переключения пользователь ожидает немедленного эффекта и обратимости без отдельных «Сохранить».
Чекбокс = выбор опций. Может применяться сразу или по кнопке — важно явно показать модель («Настройки сохранены» / «Нажмите Сохранить»).
Радио = выбор режима. Переход может перестраивать интерфейс. Сигнализируйте изменения (микроанимация/текст).
4) Состояния и визуальная семантика
Normal / Hover / Focus / Active / Disabled / Error. Контраст текста и индикаторов ≥ AA.
Tri-state (чекбокс): пусто / частично / выбрано. Частичное состояние некликабельно само по себе — клик меняет на «выбрано», а не «пусто».
Свитч: имеет четкое различие «вкл/выкл» по цвету и положению «бегунка». Цвет — не единственный носитель смысла (иконка/лейбл рядом).
5) Копирайтинг и подписи
Глагол + объект или утверждение, которое становится истинным при выборе.
Чекбокс: «Получать e-mail-уведомления».
Свитч: «Уведомления: Вкл/Выкл» (лейбл слева, состояние — справа или в самом свитче).
Радио: «Формат коэффициентов: Десятичный / Дробный / Американский».
Избегайте двойных отрицаний: «Не отключать…» — запутывает.
Для рискованных действий добавляйте вторичное описание: «Вкл. быстрые ставки (без подтверждения) — можно отменить в течение 5 сек.»
6) Доступность (A11y) и клавиатура
Чекбокс: `role="checkbox"`, `aria-checked="true|false|mixed"`, Space — переключение.
Свитч: нативный `<input type="checkbox">` с визуалом свитча или `role="switch"` с `aria-checked`. Поведение как у чекбокса (Space).
Радио: `role="radiogroup"` на контейнере, `role="radio"` на элементах, стрелки ↑/↓ или ←/→ — перемещают выбор, Space/Enter — подтверждают.
Группы: используйте `fieldset`/`legend` для общего контекста.
Фокус-кольца оставляйте видимыми; размеры зон клика ≥ 44×44 px на тач.
html
<! -- Radio Group -->
<fieldset role="radiogroup" aria-labelledby="odds-format">
<legend id = "odds-format "> Odds format </legend>
<label><input type="radio" name="odds" value="decimal" checked> Десятичный</label>
<label><input type="radio" name="odds" value="fractional"> Дробный</label>
<label> <input type = "radio" name = "odds" value = "american"> American </label>
</fieldset>
<! -- Checkbox (tri-state via aria) -->
<div role = "checkbox" aria-checked =" mixed" tabindex =" 0" id = "cb "> Notify about tournaments </div>
<! -- Switch (role = "switch") -->
<button role="switch" aria-checked="false" aria-labelledby="live-title" class="switch" id="live">
<span class="switch__knob"></span>
</button>
<span id = "live-title "> Live updates </span>
7) Асинхронные изменения и ошибки
Свитч + сеть: переключение → сразу оптимистичный UI → подтверждение сервера → при неуспехе мягко откатываем и показываем причину.
Чекбокс/радио по «Сохранить»: пока нет подтверждения — не меняйте глобальное поведение.
Рискованные действия: подтверждение (модалка) или undo-панель на 5–10 сек (если регламент допускает).
js
//Optimistic for switch const sw = document. getElementById('live');
sw. addEventListener('click', async ()=>{
const prev = sw. getAttribute('aria-checked') === 'true';
sw. setAttribute ('aria-checked', String (! prev)) ;//instantly try {
const r = await fetch('/api/live', { method:'POST', body: JSON. stringify({ enabled:!prev })});
if(!r.ok) throw new Error();
} catch {
sw. setAttribute('aria-checked', String(prev)); // откат
//show the toast "Failed to enable live"
}
});
8) Мобильные паттерны
Свитч — основной бинарный контрол в настройках на мобильных.
Радио можно заменить segmented control для 2–4 опций (лучше попадание пальцем).
Чекбоксы в списках — с крупной областью клика и поддержкой быстрого мультивыбора.
9) Паттерны группировки и макета
Радио: вертикальный список (лучше сканируется), для 2–3 вариантов — сегменты в одну строку.
Чекбоксы: выравнивание по одной колонке; для длинных списков — «Выбрать все» + tri-state у группы.
Свитч: лейбл слева, контрол справа на одной линии; показывайте текущее состояние текстом при необходимости («Вкл»/«Выкл»).
10) Антипаттерны
Свитч, который не применяет изменения сразу (требует «Сохранить»).
Радиокнопки, где возможен множественный выбор.
Чекбокс для взаимоисключающих вариантов («Мужской/Женский» как два чекбокса).
Бинарный свитч для опасного необратимого действия (удалить данные).
Двойные отрицания в тексте.
Изменение макета при ошибке так, что фокус теряется.
11) Специфика iGaming (примеры)
Формат коэффициентов: радиогруппа «Десятичные / Дробные / Американские» — применяется сразу и сохраняется в профиль.
Быстрая ставка: свитч «Быстрые ставки (без подтверждения)» с явным описанием и undo на 5–10 сек после каждой операции.
Подписки/уведомления: чекбоксы по типам событий (выигрыши, турниры, депозиты). Групповой чекбокс «Выбрать все» — tri-state.
Live-обновления коэффициентов: свитч «Live-режим» с оптимистикой и откатом при ошибке сети.
Лимиты ответственной игры: радиокнопки для периодов (день/неделя/месяц) + поле суммы; подтверждение измененного лимита с вступлением «с завтрашнего дня».
12) Токены дизайн-системы (пример)
json
{
"checkbox": { "size": 20, "radius": 4, "gap": 8 },
"radio": { "size": 20, "dot": 10, "gap": 8 },
"switch": { "width": 44, "height": 24, "knob": 20, "padding": 2 },
"focusRing": { "width": 2, "offset": 2 },
"motion": { "toggleMs": 140, "ease": "cubic-bezier(0. 2,0,0. 2,1)" },
"a11y": { "contrastAA": true }
}
CSS-пресеты (концепт):
css
.control { display:flex; align-items:center; gap:8px; min-height:36px; }
.switch { width:44px; height:24px; padding:2px; border-radius:999px; background:var(--bg-muted); position:relative; }
.switch[aria-checked="true"]{ background:var(--accent); }
.switch__knob{ position:absolute; width:20px; height:20px; border-radius:50%; left:2px; top:2px; transition: transform. 14s cubic-bezier(.2,0,.2,1); background:#fff; }
.switch[aria-checked="true"].switch__knob{ transform: translateX(20px); }
.control:focus-visible{ outline:2px solid var(--focus); outline-offset:2px; }
13) Сниппеты UX-логики
Tri-state «Выбрать все»:js function updateMaster(master, items){
const total = items. length, checked = items. filter(i=>i. checked). length;
master. indeterminate = checked>0 && checked<total;
master. checked = checked===total;
}
Радиогруппа с клавиатурой (стрелки):
js const radios = [...document. querySelectorAll('[role="radio"]')];
let i = radios. findIndex(r => r. getAttribute('aria-checked')==='true');
document. addEventListener('keydown', e => {
if(!['ArrowRight','ArrowDown','ArrowLeft','ArrowUp'].includes(e. key)) return;
e. preventDefault();
const dir = (e. key==='ArrowRight' e. key==='ArrowDown')? 1: -1;
i = (i + dir + radios. length) % radios. length;
radios. forEach(r => r. setAttribute('aria-checked','false'));
radios[i].setAttribute('aria-checked','true');
radios[i].focus();
});
14) Метрики и эксперименты
Misclick rate и undo-частота по свитчам.
Время до выбора и ошибки валидации по радиогруппам.
Доля «Выбрать все» и сравнение с ручным выбором (скорость, точность).
A/B: копирайтинг лейблов, порядок опций, segmented vs radio, «применять сразу» vs «по кнопке».
15) QA-чек-лист
Смысл и выбор
- Контрол соответствует задаче (множественный → чекбоксы; один из N → радио; мгновенный бинарный → свитч).
- Для рискованных действий есть подтверждение/undo.
Доступность
- Корректные роли (`checkbox`/`switch`/`radiogroup`/`radio`), `aria-checked`/`indeterminate`.
- Фокус-кольца видимы, стрелки работают в радиогруппе, Space переключает чекбокс/свитч.
Поведение
- Свитч применяет изменения сразу; при ошибке — откат и сообщение.
- Tri-state у «Выбрать все» корректен; клики по лейблу работают.
Визуал
- Контраст ≥ AA; состояние не передается только цветом.
- Зоны клика ≥ 44×44 px; порядок и выравнивание стабильны.
Мобильные
- Segmented-контрол для 2–4 радио-вариантов тестирован на тач.
- Попадание пальцем и прокрутка не конфликтуют.
16) Документация в дизайн-системе
Компоненты: `Checkbox`, `Switch`, `RadioGroup`/`SegmentedControl`.
Токены размеров/анимаций/фокуса, примеры копирайтинга.
Паттерны: «Выбрать все» (tri-state), «Мгновенное применение», «Undo после риска».
Do/Don’t-галерея: свитч с отложенным сохранением (don’t), радио вместо чекбоксов (don’t), сегменты для коротких наборов (do).
Краткое резюме
Выбор контрола — это про смысл и ожидания: чекбокс — независимые флаги и группы, свитч — мгновенное включение/выключение функции, радио — ровно один вариант из набора. Поддержите доступность, продумайте асинхронные состояния и копирайтинг — и пользователи будут уверенно менять настройки без ошибок и сюрпризов.