Перейти к содержимому
EN
Масштаб
Плотность
Тема
Акцент

Обратная связь

Скелетон

Место, где содержимое ещё не пришло. Библиотеке про ожидание нужен примитив ожидания содержимого.

Компонент
Разметка
<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-sunkenlight-dark(var(--n-2), var(--n-14))база +1: тема
--radius-xs4pxбаза +4: масштаб
--ease-in-outcubic-bezier(0.65, 0, 0.35, 1)одно на все ячейки

Почему кит устроен именно так — конституция · Открытый код под MIT, github.com/keshon/instrument