Основания
Ранг
Ранг говорит, сколько внимания просит место. Ставится на область и отвечает на вопрос об ЭКРАНЕ, а не о компоненте: одна и та же панель — суть одного экрана и сноска на другом.
Разметка
<div class="inst-stack">
<div class="inst-panel" data-rank="lead">
<div class="inst-panel-header"><span class="inst-panel-title">Текущий запуск</span></div>
<div class="inst-panel-body">Три агента работают, один ждёт подтверждения.</div>
</div>
<div class="inst-panel" data-rank="default">
<div class="inst-panel-header"><span class="inst-panel-title">Недавние запуски</span></div>
<div class="inst-panel-body">Четыре завершились за последний час.</div>
</div>
<div class="inst-panel" data-rank="support">
<div class="inst-panel-header"><span class="inst-panel-title">Хранение</span></div>
<div class="inst-panel-body">Транскрипты живут тридцать дней.</div>
</div>
</div>
У библиотеки эта ось была у кнопки и больше ни у чего. У кнопки четыре веса, и каждый — ответ на насколько громко это просит нажатия; у панели был один вид и ни одного вопроса, так что две панели совершенно разной важности выходили с одинаковыми вычисленными стилями, и никакая разметка не могла их различить.
Законы, которым подчиняется ранг, и причина, по которой это атрибут, а не модификатор, — в принципах дизайна. Здесь материал: значения, во что каждое разрешается и как выбирать.
Контракт
| Что | Обязательно | Почему |
|---|---|---|
| Значение из словаря | да | lead · default · support. Значение вне словаря не делает ничего — обычный режим отказа любого закрытого словаря здесь |
| На области | да | Панель, карточка или секция. В остальных местах бездействует: канал никто больше не читает |
Не больше одного lead на экран |
да | Две ведущих — ни одной. Проверяется на отрисованном дереве через kitAudit.composition() |
Написанный data-rank="default" |
нет, но желательно | Отсутствие разрешается в него. Написанное значение делает опечатку опечаткой, а не базой |
| Ранг на всех областях композиции, если он есть хоть у одной | да | Половина экрана не может объявить иерархию, пока вторая половина молчит |
Доступность
| Ранг — не состояние | Он не несёт смысла, и его ничто не озвучивает. Что область ЗНАЧИТ — это тон, а статус всегда идёт со словом |
| Контраст на каждом ранге | Каждая ступень измерена против каждого фона, на котором может стоять, в пяти темах и четырёх акцентах. support берёт --text-muted — самый тихий ярус, которым текст ещё можно читать; --text-faint — порог декорации и для чтения запрещён |
| Пол кегля | support берёт --region-title-support, то есть --text-2xs — объявленное дно шкалы и единственное место, где подпись размером с бейдж уместна: тихая область по определению сноска. Ниже не идёт ничего |
| Уровень заголовка | Ранг его не трогает. <h2 class="inst-section-title"> остаётся настоящим h2 при любом ранге: тег несёт структуру, ранг — размер |
Шкала
Три значения, список закрыт.
| Значение | Имя | Тон | Фон | Рамка |
|---|---|---|---|---|
lead |
--text-sm |
без изм. | без изм. | без изм. |
default |
--text-xs |
без изм. | без изм. | без изм. |
support |
--text-2xs |
--text-muted |
одна плёнка | нет |
Ранг не меняет геометрию. Ни отступа, ни угла, ни размера чего бы то ни было. Это и есть разделение двух осей, и его стоит сказать прямо:
| владеет | |
|---|---|
| Вложенность | геометрией — отступ, угол, направление фона |
| Ранг | регистром — ступень и тон имени, рамка, плёнка фона |
Соседи делят сетку. Три панели, разложенные на странице, не вложены друг в друга, их края содержимого читаются колонкой, и сдвиг одной на несколько пикселей говорит не «тише», а «съехало»: глаз ловит сломанное выравнивание намного раньше, чем отступ. Ранг не двигает ни одного края, поэтому области держат сетку при любых рангах.
Вложенная область — другой случай, и им занимается вложенность: она действительно внутри контейнера, поэтому шаг внутрь и есть то, как выглядит «внутри», и никакого выравнивания через границу никто не обещал.
Вся лестница стоит ниже базы, и ничто не растёт, чтобы обозначить важность.
Имя ведущей области доходит до --text-sm — размера обычного интерфейсного
текста; имя обычной стоит ступенью ниже, тихой — двумя.
Значит, обычная подпись мельче данных, которые подписывает: третий закон всегда имел в виду это, а кит оставлял это одному начертанию. Ведущая подпись — единственное исключение: она совпадает с данными по кеглю и отличается начертанием, как когда-то отличались все. Ведущая на экране одна, и это то место, где взгляд должен остановиться.
Иерархию делает то, что вокруг становится тише, а не то, что важное становится
громче. Заодно оформление не дотягивается до содержания: --text-md принадлежит
прозе и ответу агента, и имя области не достаёт до него ни при каком ранге.
lead двигает одно — имя, на ступень. Поднимать область некуда:
--surface-raised во всех светлых темах потолок шкалы, так что поднимающийся
lead нашёл бы запас в двух темах из пяти и молча ничего не делал бы в трёх.
support может потратить больше: снятие — дешёвое направление, поэтому
ступень вниз, ярус тона вниз, плёнка и никакой рамки.
Токены за этим
Ступени — ссылки в шкалу кегля, а не числа, поэтому шкала несёт их вместе со всем остальным. Плотность их не трогает: она не трогает кегль.
| Токен | Значение |
|---|---|
--region-title-lead |
--text-sm |
--region-title-default |
--text-xs |
--region-title-support |
--text-2xs |
--region-ground-support |
--surface-recessed |
--region-edge-support |
прозрачно |
Токен заводится только там, где ранг отличается от default. Своих
токенов фона и рамки у lead нет, и это модель, а не упущение: lead не
поднимает, и называть нечего.
Поведение
Ранг не наследуется
Область внутри ведущей области, если у неё нет своего ранга, — default.
Ведущая область ведёт экран, а не своё содержимое: наследующийся ранг был бы
общим регулятором яркости под красивым именем.
Разметка
<div class="inst-panel" data-rank="lead">
<div class="inst-panel-header"><span class="inst-panel-title">Ведущая панель</span></div>
<div class="inst-panel-body inst-stack inst-stack--tight">
<div class="inst-card"><div class="inst-card-title">Обычная карточка</div></div>
<div class="inst-card" data-rank="support"><div class="inst-card-title">Тихая</div></div>
</div>
</div>
Ранг — не глубина
Направление задаёт вложенность: область внутри области утопает всегда и не спрашивая ранга. Ранг задаёт присутствие. Видно, что оси не соприкасаются, на ведущей карточке внутри тихой панели: карточка поднимается именем и всё равно утопает фоном, потому что это разные вопросы.
Область берёт не больше одной плёнки. Её просит вложенность и её же просит
support, и область, получившая обе просьбы, всё равно красит одну: глубина
набирается стопкой отрисованных элементов, а не силой одной заливки. Поэтому
рычаг ранга по фону работает только на нулевой глубине, а тихая область глубже
показывает ранг именем и снятой рамкой. См. высоту.
Ранг — не тон
Ведущая область — главная, а не хорошая, и оси независимы: ранг говорит, куда смотреть, тон — что это значит. Они складываются, и ради этого сочетания оси и держат порознь: область, которой принадлежит экран, и при этом в ошибке:
Разметка
<div class="inst-panel" data-rank="lead" data-tone="error">
<div class="inst-panel-header">
<span class="inst-panel-title">База недоступна</span>
<span class="inst-panel-actions"><span class="inst-badge" data-tone="error"><span class="inst-dot"></span>P1</span></span>
</div>
<div class="inst-panel-body">Началось в 03:12. Три попытки, ни одной удачной.</div>
</div>
Тон идёт на фон, но не на рамку — ровно так же, как
баннер: он оставляет --border и кладёт тон
на фон. Тонированный бокс ещё и в тонированной рамке говорит один факт дважды.
На фоне тон старше ранга. Тихая область, которая при этом в ошибке, — это
ошибка, нарисованная тихо: ступень, тон текста и снятая рамка по-прежнему
говорят support, а фон говорит error. Смысл выигрывает то единственное
свойство, за которое они спорят.
Не наследуется — по той же причине, что и ранг. Карточка внутри тонированной панели показывает её тон, только если попросит сама.
Правила
Что брать, а что нет
| Взять | Вместо |
|---|---|
| Ранг, чтобы сказать, какая область — суть экрана | Заголовок покрупнее в разметке: размер заголовка интерфейса — вопрос ранга, а не уровня. См. типографику |
| Тон, чтобы сказать, что область значит | lead в смысле «хорошо» или «срочно»: ранг не несёт смысла, и его ничто не озвучивает |
| Плотность, чтобы область стала плотнее | support, чтобы влезло больше: ранг меняет вес присутствия, а не размер геометрии |
| Вес кнопки, чтобы сказать, как громко просит действие | Ранг на контроле: кнопка уже отвечает на этот вопрос четырьмя весами, а две оси на один вопрос — одна ось с двумя именами |
| Панель внутри половины сплита, с рангом | Ранг на самой половине: примитив раскладки не рисует, а рисующий нельзя было бы вложить во что-то, что рисует иначе |
Когда не брать вовсе
Экран без иерархии ранга не берёт. Пример библиотека возит с собой: в блоке чата единица — реплика, и все реплики равны, поэтому ранга там нет ни у чего. Ось, применимая везде, — украшение; ось, отказывающаяся от случая, делает свою работу.
API
| Имя | Значение | Что делает |
|---|---|---|
| attribute | ||
data-rank | — | lead default support. Ставится на область; отсутствие атрибута разрешается в default |
| Имя | Значение | Откуда |
|---|---|---|
| token | ||
--region-title-lead | var(--text-sm) | одно на все ячейки |
--region-title-default | var(--text-xs) | одно на все ячейки |
--region-title-support | var(--text-2xs) | одно на все ячейки |
--region-ground-support | var(--surface-recessed) | одно на все ячейки |
--region-edge-support | transparent | одно на все ячейки |
--region-title-size | var(--region-title-default) | база +3: |
--region-title-ink | var(--text-primary) | база +2: |
--region-ground | var(--surface-raised) | база +4: |
--region-edge | var(--border) | база +3: |
Почему кит устроен именно так — конституция · Открытый код под MIT, github.com/keshon/instrument