Индикаторы прогресса и статусов
1) Принципы
1. Моментальный отклик (≤ 100 мс). Любое действие сразу подтверждается визуально: нажатие → `busy`/скелет/микроанимация.
2. Честность и предсказуемость. Проценты отражают реальный прогресс, а не «вечный 99%». Если оценка невозможна — используйте не определенный (indeterminate) вариант и пояснение.
3. Контекст рядом с действием. Индикатор там, где пользователь смотрит/действует (кнопка, карточка, блок), а не в дальнем углу.
4. Незаметность после успеха. Успех — короткий чек/фейд и все. Ошибка — понятное объяснение и безопасный повтор.
5. Доступность по умолчанию. `role="progressbar"`, `aria-valuenow`, live-регионы, контраст ≥ AA.
2) Типы индикаторов и когда их использовать
Линейный прогресс (determinate/indeterminate). Загрузка/импорт/экспорт, шаги с понятным объемом.
Круговой прогресс (обычно indeterminate). Короткие локальные операции в компактных местах.
Степпер (пошаговый). Последовательные этапы («Шаг 2 из 4»), KYC, мастер-процессы.
Skeleton (скелетон-заглушки). Для подстановки структуры контента вместо спиннеров; избегайте «shimmer» для пользователей с `prefers-reduced-motion`.
Статус-бейджи (success/warning/danger/info). Состояние объекта («В обработке», «Отклонено», «Готово»).
Баннер/тост статуса. Глобальные события: оффлайн, сбой сервера, синхронизация очереди.
Inline loader (кнопка/строка). Локальные операции: «Сохранение…», «Отправка…».
3) Определенный vs неопределенный прогресс
Determinate: известен объем работы → показываем %/этапы.
Indeterminate: объем неизвестен → «Идет обработка…» + контекст («Обычно до 1–2 мин»).
Смена состояний: можно начать с indeterminate → перейти к determinate, когда появится оценка.
ETA осторожно: показывайте диапазон («~30–60 сек») и избегайте «обещаний».
4) Размещение и паттерны
Локально к действию: кнопка `aria-busy`, спиннер в строке таблицы, прогресс в карточке.
Над блоком/списком: линейный бар под хедером секции при пакетных операциях.
Глобально: верхний тонкий прогресс (route-change), системные баннеры.
Sticky-панель (моб.): подтверждение/прогресс по CTA в нижнем доке.
5) Доступность (A11y)
Прогресс:html
<div role = "progressbar" aria-valuemin =" 0" aria-valuemax =" 100" aria-valuenow =" 42" aria-label = "Load Report "> </div>
Indeterminate: выставьте `role="progressbar"` без `aria-valuenow`, добавьте поясняющий текст в `role="status"`.
Лайв-регионы: `aria-live="polite"` для обычных обновлений, `assertive` — только для критичных.
`aria-busy="true"` на контейнере, который временно блокирован действиями.
Фокус не «скачет»: при смене этапа перемещайте фокус на заголовок шага степпера.
6) Копирайтинг и визуальная семантика
Коротко и по делу: «Идет загрузка…», «Обрабатываем платеж…».
Добавьте «что дальше»: «Готово. Обновим страницу автоматически».
Цвета: зеленый — успех, оранжевый — предупреждение/внимание, красный — ошибка. Цвет ≠ единственный носитель смысла: дайте иконку/текст.
7) Оптимистические обновления и откаты
Оптимистика: меняем UI сразу (например, отметка «В избранном») и тихо подтверждаем сервером.
При ошибке — мягкий откат + объяснение и `Retry`.
Критичные операции (ставка/платеж): опционально «мягкая оптимистика» (фиксируем «Отправлено → Ожидаем подтверждение…»), но без изменения денежного состояния до подтверждения.
8) Очереди и фоновые задачи
Показывайте очередь: `n` задач в обработке, отдельные карточки с прогрессом.
Дайте паузу/отмену для долгих операций, если возможно.
Фоновая обработка: бейдж «В фоне», тосты по завершении, раздел `История задач`.
9) Перформанс и тайминги
Первая реакция ≤ 100 мс: применяйте skeleton/inline-busy вместо пустоты.
Анимации: 120–180 мс (in), 80–140 мс (out), только `transform/opacity`.
Длинные процессы: обновление прогресса не чаще 10–15 раз/сек; группируйте изменения.
10) Сниппеты
Локальный прогресс у кнопки
html
<button id="export" class="btn" aria-busy="false">Экспорт CSV</button>
<script>
const btn = document. getElementById('export');
btn. addEventListener('click', async () => {
btn. setAttribute('aria-busy','true'); btn. disabled = true;
try {
const r = await fetch('/api/export', { method:'POST' });
if(!r.ok) throw new Error();
//show toast "Export has begun. We will notify upon readiness"
} catch {
//toast with cause and Retry
} finally {
btn. disabled = false; btn. setAttribute('aria-busy','false');
}
});
</script>
Линейный determinate
html
<div class="progress">
<div class="bar" role="progressbar" aria-valuemin="0" aria-valuemax="100" aria-valuenow="0"></div>
</div>
<style>
.progress{height:4px; background:var(--bg-muted); border-radius:999px; overflow:hidden}
.progress. bar{height:100%;width:0%;background:var(--accent); transition:width. 16s}
</style>
<script>
const bar = document. querySelector('.progress. bar');
let n=0; const t=setInterval(()=>{ n=Math. min(100, n+5); bar. style. width=n+'%'; bar. setAttribute('aria-valuenow',n); if(n===100) clearInterval(t); },160);
</script>
Степпер
html
<nav aria-label = "Progress">
<ol class="steps">
<li class = "done "> <span> 1 </span> Data </li>
<li class = "current" aria-current = "step "> <span> 2 </span> Documents </li>
<li> <span> 3 </span> Confirmation </li>
</ol>
</nav>
11) Skeleton правильно
Используйте форму будущего контента (карточки/строки), без бесконечного shimmer (или отключайте при `prefers-reduced-motion`).
Предел времени: если загрузка > 300–500 мс, skeleton оправдан; при меньших задержках достаточно «микро-фейда».
12) Статус-бейджи (объектные состояния)
Примеры: Черновик, В обработке, Ожидает подтверждения, Готово, Отклонено.
Короткий текст, устойчивые цвета иконки/фона, контраст ≥ AA.
Иконка `aria-hidden="true"` + текстовый лейбл (для SR).
На клик — раскрываем детали или открываем «Историю».
13) Специфика iGaming
Ставка:- Нажатие CTA → «Отправлено…», при задержке > 3 с — «Ожидаем подтверждение…» (indeterminate).
- Успех — «Ставка принята» + чек; ошибка — честное объяснение («рыночный период закрыт/коэффициент изменился») и безопасный Retry.
- Determinate по этапам: «Проверка метода → Отправка → Подтверждение PSP».
- Для вывода — бейдж В обработке, экран статуса в профиле, ETA диапазоном; пуш по завершении.
- Степпер регистрации (шаги), прогресс до награды (N/очков), бейдж статуса «Участвует».
- Реал-тайм обновление — аккуратно, без миганий, с `aria-live="polite"`.
- Степпер + бейдж «На проверке». Показывайте, что уже принято (галочка) и что осталось.
14) Цвета, контраст и текст
Success / Info / Warning / Danger — четыре устойчивых тона в дизайн-системе.
Контраст текста к фону бейджа ≥ AA.
Не используйте один и тот же цвет для «в обработке» и «предупреждения».
15) Метрики
Time-to-First-Feedback (TTFF): от клика до первого визуального отклика.
Completion Time по операциям и drop/abort rate для долгих задач.
Retry success rate для операций с прогрессом.
% оптимистик, завершившихся успешно (и доля откатов).
Visible time skeleton/spinner (цель: как можно меньше).
16) Анти-паттерны
«Немая» кнопка (нет busy/спиннера) > 100 мс.
Бесконечные спиннеры без объяснения и альтернативы.
Ложные проценты/ползунок, зависший на 99%.
Сброс контента при ошибке без возможности повторить.
Только цвет без текста/иконок для статуса.
Прогресс далеко от места действия (пользователь не видит).
17) Токены дизайн-системы (пример)
json
{
"progress": {
"barHeight": 4,
"radius": 999,
"inMs": 160,
"outMs": 120,
"pollHz": 10
},
"status": {
"tones": { "success": "#", "info": "#", "warning": "#", "danger": "#" },
"badge": { "radius": 8, "px": "6 10", "icon": 14 }
},
"skeleton": {
"rowHeight": 16,
"gap": 8,
"reduceMotion": true
},
"a11y": {
"useAriaBusy": true,
"live": "polite",
"contrastAA": true
}
}
CSS-пресеты:
css
.badge{display:inline-flex; gap:6px; align-items:center; padding:6px 10px; border-radius:8px; font-size:.875rem}
.badge--success{background:var(--bg-success); color:var(--on-success)}
.skeleton{background:linear-gradient(90deg, var(--sk1), var(--sk2), var(--sk1)); border-radius:8px}
@media (prefers-reduced-motion: reduce){.skeleton{background:var(--sk1)} }
18) QA-чек-лист
Отклик и честность
- TTFF ≤ 100 мс; есть локальный busy/skeleton.
- Determinate — реальный %; indeterminate — с пояснением.
Доступность
- `role="progressbar"`/`aria-valuenow` корректны; live-регионы на обновлениях.
- Контраст бейджей/текста ≥ AA; цвет не единственный носитель смысла.
Поведение
- Оптимистика с корректным откатом и объяснением.
- Очереди отображаются; есть отмена/пауза (если применимо).
- Прогресс рядом с местом действия, не перекрывает CTA.
Перформанс
- Обновления не чаще 10–15 раз/сек; анимации `transform/opacity`.
- Skeleton не дразнит shimmer’ом при `reduce-motion`.
Тексты
- Коротко, без техжаргона; «что дальше» после завершения.
- Без «обещаний» точного времени, если оно не гарантируется.
19) Документация в дизайн-системе
Компоненты: `ProgressBar`, `ProgressCircle`, `Stepper`, `StatusBadge`, `InlineLoader`, `Skeleton`.
Правила выбора типа, копирайтинг и цвета для статусов.
Паттерны: оптимистика, очереди, фоновая обработка, оффлайн-синхронизация.
Do/Don’t-галерея: «вечный спиннер», ложные проценты, «немой» CTA vs хороший TTFF.
Краткое резюме
Индикаторы прогресса и статусов должны давать своевременную, честную и доступную обратную связь. Размещайте их рядом с действием, различайте определенный и неопределенный прогресс, уважайте a11y и не злоупотребляйте анимациями. В iGaming это особенно важно для ставок, платежей, турниров и KYC — спокойный, предсказуемый прогресс напрямую повышает доверие и конверсию.