Навигация
Крошки
Путь от корня до текущего экрана. Отвечает на вопрос «где я и как отсюда выбраться на уровень выше», а не «какие ещё есть разделы».
Разметка
<nav aria-label="Хлебные крошки">
<ol class="inst-crumbs">
<li><a href="#">Проекты</a></li>
<li><a href="#">worldgen</a></li>
<li><span aria-current="page">Прогон #4127</span></li>
</ol>
</nav>
Использование
Крошки — упорядоченный список внутри <nav>, и оба элемента обязательны:
<ol> сообщает порядок и длину пути, <nav aria-label> даёт ориентир, который
отличим от остальных навигаций экрана.
<nav aria-label="Хлебные крошки">
<ol class="inst-crumbs">
<li><a href="/projects">Проекты</a></li>
<li><span aria-current="page">worldgen</span></li>
</ol>
</nav>
| Что | Обязательно | Почему |
|---|---|---|
<nav> + aria-label |
да | Навигаций на экране несколько; без имени крошки неотличимы от остальных ориентиров |
<ol> с <li> |
да | Путь упорядочен, и порядок — часть смысла. <div> его теряет |
aria-current="page" на последнем |
да | Помечает текущий экран и получает --text-primary вместо приглушённого |
Последний элемент — не <a> |
да | Ссылка на страницу, где уже находишься, — ложное действие |
Отдельного класса у элемента и у ссылки нет: кит оформляет & > li и & a
внутри списка. Разметка и есть API.
Когда использовать
| Используйте | Возьмите другое |
|---|---|
| Экран лежит в иерархии глубже второго уровня | Список равноправных разделов — навигация: у крошек нет полноты, только путь |
| Нужен быстрый выход на уровень выше | Переключение видов одного объекта — вкладки: это братья, а не предки |
| Путь в шапке оболочки, рядом с действиями | Последовательность шагов процесса — шаги мастера: у них есть состояние, у крошек нет |
| — | Заголовок экрана — шапка экрана. Крошки не заменяют название |
Устройство
Шеврон между элементами рисует li + li::before — псевдоэлемент, а не символ в
разметке. Два следствия, ради которых так и сделано:
- разделитель не попадает в текст: скринридер и копирование получают «Проекты worldgen Прогон #4127», а не строку с угловыми скобками;
- форма приходит маской, цвет — токеном
--text-faint. Цвета внутри data-URI в ките нет, поэтому шеврон переживает смену темы и режим принудительных цветов без второй копии картинки.
Полоса переносится (flex-wrap): длинный путь в узкой шапке уходит на вторую
строку, а не выталкивает документ за вьюпорт.
Правила
Так Последний элемент — не ссылка
Это текущий экран, вести с него некуда. <span aria-current="page"> даёт и
отсутствие перехода, и озвучивание.
Не так Крошки вместо навигации
Путь не показывает, какие ещё есть разделы. Полнота — работа навигации, у крошек её нет по определению.
Так Разделитель псевдоэлементом
Шеврон не попадает ни в копирование, ни в дерево доступности — там ему делать нечего.
Не так Символ разделителя в разметке
› в тексте озвучивается и копируется вместе с путём, превращая его в строку с
угловыми скобками.
Доступность
| Клавиатура | Нативные ссылки. Tab — обход, Enter — переход |
| Ориентир | <nav aria-label="Хлебные крошки"> — отдельная точка в списке ориентиров |
| Разделитель не читается | Шеврон — псевдоэлемент, его нет ни в тексте, ни в дереве доступности |
| Контраст | Путь — --text-muted (4.5:1), а не --text-faint: --text-faint это порог декорации, и текст, который читают, им не красится. Шеврон — наоборот, декорация |
| Наведение | Ссылка получает подчёркивание и полный цвет: подчёркивание работает там, где цвет не различается |
| Кегль | --text-xs. Путь тише заголовка экрана, который он предваряет |
API
| Имя | Значение | Что делает |
|---|---|---|
| класс | ||
inst-crumbs | — | Список пути. Ставится на <ol> |
| токен | ||
--space-2 | 4px | |
--text-xs | 0.75rem | |
--size-chevron | 10px | |
--text-muted | light-dark(var(--n-8), var(--n-6)) | |
--text-faint | light-dark(var(--n-7), var(--n-7)) | |
--text-primary | light-dark(var(--n-12), var(--n-1)) | |
Почему кит устроен именно так — конституция · Открытый код под MIT, github.com/keshon/instrument