Основания
Плотность
Плотность — атрибут контейнера. Один атрибут на панели перенастраивает всё внутри неё: меняется ярус ролей, а собственных чисел компоненты не содержат.
Разметка
<div class="inst-cluster" data-density="compact">
<button class="inst-btn inst-btn--sm" type="button">sm</button>
<button class="inst-btn" type="button">md</button>
<span class="inst-badge" data-tone="ok"><span class="inst-dot"></span>готово</span>
<input class="inst-input inst-input--sm" type="text" value="compact">
</div>
Использование
<section data-density="compact">
<!-- всё внутри перенастроено -->
</section>
Атрибут наследуется через каскад пользовательских свойств, поэтому работает на любой глубине и на любом контейнере. Вложение допустимо: внутренняя область с другим значением перекрывает внешнюю.
| Значение | Для чего |
|---|---|
| атрибута нет | Умолчание. Панельный инструмент, дашборд, большинство экранов |
data-density="compact" |
Плотный табличный вид: очередь агентов, лог, дерево, инспектор свойств |
data-density="comfortable" |
Формы, настройки, мастера — там, где решений мало, а каждое требует внимания |
Когда использовать
| Используйте | Возьмите другое |
|---|---|
compact для плотного табличного вида: очередь, лог, инспектор |
compact для основной навигации — цели нажатия уходят ниже порога, см. предупреждение и оболочку |
comfortable для формы и настроек, которые заполняют вдумчиво |
comfortable для длинного списка — на экран влезает вдвое меньше строк, чем нужно строке очереди |
| Атрибут на контейнере — панели, секции, диалоге | Атрибут на каждом компоненте — плотность не вариант. Размер контрола выбирает --sm/--lg у кнопки |
| Умолчание — ничего не писать | Своя плотность числом в приложении — новое значение заводится ролью, список ролей в токенах |
| Смена плотности целиком у области | Смешение плотностей в одной таблице — колонки разъедутся, см. таблицу |
Шкала
Ровно ярус ролей, и этого достаточно.
Высоты и отступы контролов
| Токен | compact |
по умолчанию | comfortable |
|---|---|---|---|
--control-h-xs |
18px | 20px | 22px |
--control-h-sm |
22px | 26px | 30px |
--control-h-md |
26px | 32px | 36px |
--control-h-lg |
32px | 38px | 44px |
--control-pad-sm |
--space-3 |
--space-4 |
--space-5 |
--control-pad-md |
--space-4 |
--space-5 |
--space-6 |
--control-pad-lg |
--space-5 |
--space-6 |
--space-7 |
Отступы областей
| Токен | compact |
по умолчанию | comfortable |
|---|---|---|---|
--pad-panel |
--space-4 |
--space-5 |
--space-6 |
--pad-card |
--space-5 |
--space-6 |
--space-7 |
--pad-cell-x |
--space-3 |
--space-4 |
--space-5 |
--row-pad-y |
--space-2 |
--space-3 |
--space-5 |
--gap-row |
--space-2 |
--space-3 |
--space-4 |
--gap-inline |
--space-3 |
--space-4 |
--space-5 |
Глифы и жёлобы
| Токен | compact |
по умолчанию | comfortable |
|---|---|---|---|
--size-check |
13px | 15px | 17px |
--size-switch-w |
26px | 30px | 34px |
--size-switch-h |
15px | 18px | 20px |
--size-thumb |
12px | 14px | 16px |
--size-spinner |
12px | 13px | 13px |
--size-gutter |
12px | 14px | 16px |
--size-indent |
12px | 14px | 16px |
--label-col |
78px | 92px | 104px |
Что НЕ перенастраивается
| Что | Почему |
|---|---|
| Кегль | Плотность — про геометрию. Уменьшать текст вместе с отступами значит упираться в пол в 11px через один шаг |
| Цвет и контраст | Пороги не зависят от того, сколько строк влезло на экран |
| Радиусы | Форма объекта не меняется от того, насколько тесно он стоит |
--size-dot, --size-marker, --size-icon |
Носители значения. Точка на 4px не читается, метка на 1px не видна |
--space-* |
Шкала — фундамент. Плотность двигает роли, а не шкалу под ними |
Поведение
Ярус ролей объявлен с нулевой специфичностью. Это не стилевая мелочь:
дефолт с той же специфичностью, что и переопределение, — это не дефолт, а
правило, объявленное позже. Ровно на этом --row-pad-y когда-то не
реагировал на плотность вообще.
Отсюда же следует, что приложение переопределяет любую роль без борьбы:
.my-inspector { --label-col: 120px; }
Правила
Компонент, который ломается в compact, содержит зашитую константу, которая
должна быть ролью. Три плотности — обязательный прогон при добавлении
компонента, наравне с проверкой контраста.
Доступность
Цели нажатия
WCAG 2.5.8 (AA) требует цель нажатия не меньше 24×24 CSS-пикселей. В плотности
compact контрол размера sm даёт 22px — ниже порога. Это осознанный
размен: плотный табличный вид существует ради плотности.
| Плотность | --control-h-sm |
--control-h-md |
Порог 24px |
|---|---|---|---|
compact |
22px | 26px | sm не проходит |
| по умолчанию | 26px | 32px | Проходит |
comfortable |
30px | 36px | Проходит |
Правило применения: compact — плотным табличным видам, а не основной
навигации и не главным действиям экрана. Если пользователь попадает в этот
контрол мышью каждый день, он не должен быть 22px. Исключение WCAG для целей,
у которых есть эквивалент нормального размера, действует только когда такой
эквивалент действительно есть.
Остальное
| Кегль | Не уменьшается ни в одной плотности: пол в 11px остаётся полом |
| Контраст | Не зависит от плотности — те же пары проверяются один раз |
| Масштабирование текста | Высоты применяются как min-block-size, поэтому увеличенный шрифт браузера растягивает контрол, а не обрезает его. Верно во всех трёх плотностях |
| Клавиатура | Плотность не меняет порядок обхода и не прячет цели: это чистая геометрия |
API
| Имя | Значение | Что делает |
|---|---|---|
| атрибут | ||
data-density | — | compact comfortable. Отсутствие атрибута — третье, базовое значение |
| токен | ||
--control-h-xs/sm/md/lg | — | |
--control-pad-sm/md/lg | — | |
--pad-panel | var(--space-5) | |
--pad-card | var(--space-6) | |
--pad-cell-x | var(--space-4) | |
--row-pad-y | var(--space-3) | |
--gap-row | var(--space-3) | |
--gap-inline | var(--space-4) | |
--size-check | 15px | |
--size-switch-w | 30px | |
--size-switch-h | 18px | |
--size-thumb | 14px | |
--size-spinner | 13px | |
--size-gutter | 14px | |
--size-indent | 14px | |
--label-col | 92px | |
Почему кит устроен именно так — конституция · Открытый код под MIT, github.com/keshon/instrument