Обратная связь
Скелетон
Место, где содержимое ещё не пришло. Библиотеке про ожидание нужен примитив ожидания содержимого.
Разметка
<div class="inst-stack inst-stack--tight">
<div class="inst-skeleton inst-skeleton--title"></div>
<div class="inst-skeleton inst-skeleton--line"></div>
<div class="inst-skeleton inst-skeleton--short"></div>
</div>
Контракт
| Что | Обязательно | Почему |
|---|---|---|
aria-busy="true" на контейнере |
да | Скелетон — оформление, а не роль. Без атрибута для скринридера страница просто пуста |
inst-skeleton на каждой полосе |
да | База: поверхность, радиус, пульсация, высота 1lh |
| Форма повторяет будущее содержимое | да | Скелетон не той формы врёт дважды |
Высота 1lh — реальная высота строки текущего кегля. Поэтому скелетон занимает
ровно столько же, сколько займёт пришедший текст, и при подмене ничего не
прыгает.
Доступность
| Область должна объявить занятость | Скелетон — оформление, а не роль. Контейнер, который грузится, несёт aria-busy="true", иначе для скринридера страница просто пуста |
| Не читается | Полосы пусты и не содержат текста: скринридеру их читать нечем и не нужно |
| Уменьшенное движение | Пульсация замедляется до 3с, а не гаснет: индикатор занятости должен оставаться видимым |
| Амплитуда | opacity не опускается ниже 0.45: мигание с большей амплитудой раздражает периферийное зрение |
| Печать | На листе не печатается: печать статична, а ожидание на бумаге бессмысленно |
Варианты
Разметка
<div class="inst-stack inst-stack--tight">
<div class="inst-skeleton inst-skeleton--title"></div>
<div class="inst-skeleton inst-skeleton--line"></div>
<div class="inst-skeleton inst-skeleton--line"></div>
<div class="inst-skeleton inst-skeleton--short"></div>
</div>
| Класс | Ширина | Работа |
|---|---|---|
inst-skeleton |
наследует | База: поверхность, радиус, пульсация. Высота — 1lh |
inst-skeleton--title |
40% |
Заголовок абзаца |
inst-skeleton--line |
100% |
Полная строка текста |
inst-skeleton--short |
62% |
Последняя строка абзаца |
--short в конце: настоящий абзац редко заканчивается ровно по правому краю, и полоса той же длины читается как таблица, а не как текст.
Ширину можно задать и своим правилом — модификаторы лишь три частых значения.
Поведение
Пульсация
Скелетон пульсирует прозрачностью: opacity от 1 до 0.45 и обратно за
1.6с. Ключевые кадры — собственные, бесконечно.
Бегущий блик — это градиент, а градиенты в библиотеке запрещены. Но дело не только в запрете: блик изображает движение слева направо, то есть заполнение, а скелетон ничего не заполняет. Пульсация спокойнее и честнее — блок не притворяется наливающимся.
Композиции
В теле панели
Разметка
<div class="inst-panel">
<div class="inst-panel-header">
<span class="inst-panel-title">Вывод</span>
</div>
<div class="inst-panel-body">
<div class="inst-stack inst-stack--tight" aria-busy="true">
<div class="inst-skeleton inst-skeleton--title"></div>
<div class="inst-skeleton inst-skeleton--line"></div>
<div class="inst-skeleton inst-skeleton--short"></div>
</div>
</div>
</div>
Скелетон повторяет форму того, что придёт. Три полосы на месте трёх строк — это подсказка; двадцать полос на месте карточки с кнопкой — шум.
API
| Имя | Что делает |
|---|---|
| класс | |
inst-skeleton | Базовый. Обязателен всегда |
| модификатор | |
inst-skeleton--title | Ширина 40% |
inst-skeleton--line | Ширина 100% |
inst-skeleton--short | Ширина 62% |
| Имя | Значение | Откуда |
|---|---|---|
| токен | ||
--surface-sunken | light-dark(var(--n-2), var(--n-14)) | база +1: тема |
--radius-xs | 4px | база +4: масштаб |
--ease-in-out | cubic-bezier(0.65, 0, 0.35, 1) | одно на все ячейки |
Почему кит устроен именно так — конституция · Открытый код под MIT, github.com/keshon/instrument