Микровзаимодействия и фидбек
1) Что такое микровзаимодействие
Микровзаимодействия — короткие циклы «сигнал ↔ ответ», подтверждающие, что система услышала пользователя и движется к результату.
Классическая четверка:1. Триггер (клик, свайп, фокус, системное событие).
2. Правила (что и как изменяется).
3. Фидбек (визуальный/звуковой/тактильный/текстовый).
4. Цикл/мета-правила (повтор, истечение, undo/redo).
Цель: снизить неопределенность и когнитивную нагрузку, не отвлекая от задачи.
2) Принципы проектирования
Смысл > эффект. Эффект объясняет «что произошло» и «что дальше».
Мгновенность. Первый отклик ≤ 100 мс (кнопки/переключатели).
Однозначность. Различимые состояния: hover/focus/pressed/disabled/loading.
Экономия. Минимум свойств, короткие длительности, без «салютов».
Консистентность. Одинаковые действия — одинаковые сигналы.
Доступность. Фидбек видим, слышим и читаем скринридером; есть альтернатива движению/звуку.
3) Тайминги и кривые
Hover/Focus: 120–180 мс
Pressed/Toggle: 80–120 мс
Toast/Tooltip: вход 180–240 мс, выход 120–160 мс
Inline-валидация: ≤ 100 мс после утраты фокуса поля
Кривая по умолчанию: `cubic-bezier(0.2, 0, 0.2, 1)`; для pressed — ускоренная `cubic-bezier(0.4, 0, 1, 1)`.
4) Каталог микровзаимодействий
4.1 Кнопки и переключатели
Немедленный отклик: визуальный «щелк»/вдавливание + состояние `busy` при сетевом запросе.
Оптимистичное обновление: меняем UI сразу, откатываем при ошибке (с undo).
Дебаунс двойных кликов: блокируем повтор до ответа/timeout.
4.2 Inline-валидация форм
Валидация на blur поля; сообщения краткие и конструктивные («минимум 8 символов»).
Иконка статуса + цвет + текст (не цветом одним).
Для паролей — моментальный индикатор «силы» (не мешает вводу).
4.3 Тосты/баннеры/снекбары
Используйте для неблокирующих подтверждений.
Длительность 2–5 с, пауза при hover/focus, кнопка Undo где уместно.
Не закрывайте важный контент и CTA.
4.4 Прогресс и скелетоны
Если длина процесса известна — прогрессбар; если нет — skeleton вместо спиннера.
Без скачков layout: фикс. высоты блоков.
4.5 Бейджи/счетчики
Контраст цифры ≥ 4.5:1; максимум 99/999 с усечением `99+`.
Анимации инкремента — короткие шаги 40–60 мс батчами, без «дрожи» макета.
4.6 Tooltip/Help
Появление по hover/focus; доступность через `aria-describedby`.
Запрет на критичную информацию только в tooltip.
5) Ошибки, пустые состояния, undo
Ошибка: честный текст, объяснение причины и действия («Повторить», «Изменить карту»).
Пустое состояние: что это и как начать; иллюстрация приглушенная, контраст текста AA/AAA.
Undo window: 5–10 с для обратимых действий (удаление, отмена ставки до пули).
6) Мультимодальный фидбек
Звук: тихий, короткий, один паттерн на тип события (успех/ошибка/внимание); выключаем в настройках.
Вибро/хаптика: легкий отклик на press/успех; уважаем `prefers-reduced-motion` и системные ограничения.
Визуальный: только `transform/opacity`, без тяжелых blur/теней на массивах.
7) Доступность (A11y)
`:focus-visible` для клавиатуры; фокус-кольцо без blur.
Скринридер: `role="status"/"alert"` для тостов; живые регионы `aria-live="polite/assertive"`.
Альтернатива звуку/движению; `prefers-reduced-motion: reduce`.
Контраст текста и иконок — по WCAG (обычный ≥ 4.5:1).
8) Перформанс
Реагируйте за ≤ 100 мс: визуальный отклик до сети.
Анимируйте `transform/opacity`; избегайте `height/left/box-shadow` на множестве элементов.
Сетевые эффекты — с префетчем и оптимистикой; ретраи идемпотентны.
9) Токены микровзаимодействий (дизайн-система)
json
{
"micro": {
"duration": { "hover": 160, "focus": 160, "press": 90, "toastIn": 220, "toastOut": 140 },
"easing": { "std": "cubic-bezier(0. 2,0,0. 2,1)", "acc": "cubic-bezier(0. 4,0,1,1)" },
"toast": { "timeoutMs": 3500, "pauseOnHover": true },
"badge": { "max": 99, "emphasisStepMs": 50 }
}
}
10) Сниппеты реализации
Тост с паузой по hover и Undo:html
<div id="toast" role="status" aria-live="polite" hidden></div>
<script>
const toast = (msg, {undo, timeout=3500}={})=>{
const el = document. getElementById('toast');
el. innerHTML = undo? '$ {msg} <button> Undo </button>': msg;
el. hidden = false;
let t = setTimeout(close, timeout);
el. onmouseenter = () => clearTimeout(t);
el. onmouseleave = () => t = setTimeout(close, timeout);
if (undo) el. querySelector('button'). onclick = ()=>{ undo(); close(); };
function close(){ el. hidden = true; el. innerHTML=''; }
};
</script>
Inline-валидация на blur:
js const rules = { password: v => v.length>=8 "Minimum 8 characters"};
document. querySelectorAll('[data-validate]'). forEach(i=>{
i.addEventListener('blur', e=>{
const rule = rules[e. target. name]; if (!rule) return;
const ok = rule(e. target. value);
e. target. dataset. state = ok===true? 'ok': 'err';
e. target. nextElementSibling. textContent = ok===true? '': ok;
});
});
Хаптика/вибро (фолбэк):
js export const haptic = type => {
if (!('vibrate' in navigator)) return;
if (type==='success') navigator. vibrate(10);
if (type==='error') navigator. vibrate([20,40,20]);
};
CSS для «дешевых» эффектов:
css
.button{ transition: transform. 09s cubic-bezier(.4,0,1,1), box-shadow. 16s cubic-bezier(.2,0,.2,1); }
.button:active{ transform: scale(.98); }
.input[data-state="err"]{ outline: 2px solid var(--role-danger); }
.sr-only{ position:absolute; width:1px; height:1px; overflow:hidden; clip:rect(0 0 0 0); white-space:nowrap; }
@media (prefers-reduced-motion: reduce){ { animation:none! important; transition-duration:.01ms! important; } }
11) Метрики и контроль качества
INP p75 < 200 мс, доля Long Tasks < 5%.
First User Feedback (клик→визуальный отклик) ≤ 100 мс.
Доля оптимистичных действий с откатом < 3% (иначе — недоверие).
UX-опросы: понятность сообщений об ошибках, видимость подтверждений.
QA-чек-лист
- У каждого интерактива есть `pressed/busy/disabled`.
- Ошибки сопровождаются текстом и действиями (Retry/Undo).
- Тосты доступны по SR и не перекрывают ключевой контент.
- Inline-валидация не мешает вводу; сообщения конкретны.
- Поддержан `prefers-reduced-motion`; звук/вибра выключаемы.
- Нет скачков layout и строба; анимации на `transform/opacity`.
12) Специфика iGaming
Ставка/покупка: мгновенный `pressed→busy`, тост «Принято» с Undo (если регламент позволяет), idempotent-ключи; при задержке > 1 с — «Ожидаем подтверждение…».
Spin/Reveal: короткий пресс-фидбек, плавный старт/стоп без бесконечного мигания; выигрыш — всплеск ≤ 500 мс + читабельный текст (AAA).
Лайв-коэффициенты: обновления батчами, визуальный дифф (стрелка/толщина) без «прыжков».
Платежи/выводы: пошаговый прогресс (KYC→Проверка→Выплата), прозрачные тексты причин отказа.
Ответственная игра: уведомления без отвлекающих эффектов; высший контраст, явные CTA «Установить лимит».
13) Анти-паттерны
Ждать сетевого ответа, прежде чем показать отклик на клик.
«Цвет без формы»: состояние отличается только оттенком.
Бесконечные пульсации/мигания, резкие звуки без выключателя.
Tooltip с критичным контентом, недоступным с клавиатуры.
Спиннер в пустоте > 1–2 с без прогресса/скелетона.
Тонкие тени/blur на сотнях элементов (лаг на слабых устройствах).
14) Документация в дизайн-системе
«Micro-tokens»: `duration/easing`, пресеты тостов/бейджей/валидаторов.
«Patterns»: кнопки, формы, тосты, прогресс, inline-ошибки, undo.
«A11y & Motion»: правила для SR/HC/reduced-motion; примеры ARIA.
«Do/Don’t»: короткие клипы с таймингами, цифрами INP/First Feedback.
Краткое резюме
Микровзаимодействия — это язык уверенности. Давайте отклик за ≤ 100 мс, фиксируйте понятные состояния, используйте оптимистику с безопасным откатом, не полагайтесь только на цвет и анимируйте легкие свойства. Уважайте доступность и производительность — тогда продукт ощущается живым, честным и надежным, особенно в сценариях реального времени.