Перейти к содержанию

Навигация

Навигация — ключевой элемент любого сайта или приложения, и начинается она с HTML.

Как вы узнали в разделе "ссылки", элемент <a> с атрибутом href создает ссылки, по которым пользователи могут переходить, щелкая или касаясь их. В разделе о списках вы узнали, как создавать списки содержимого. В этом разделе вы узнаете, как группировать списки ссылок для создания навигации.

Существует несколько типов навигации и несколько способов их отображения. Именованные якоря в тексте, ссылающиеся на другие страницы в пределах одного сайта, считаются локальной навигацией. Локальная навигация, состоящая из ряда ссылок, отображающих иерархию текущей страницы по отношению к структуре сайта, или страницы, по которым пользователь перешел, чтобы попасть на текущую страницу, называется хлебной крошкой.

Оглавление страницы — это еще один вид локальной навигации. Страница, содержащая иерархические ссылки на все страницы сайта, называется картой сайта. Раздел навигации, ведущий к страницам верхнего уровня сайта и присутствующий на каждой странице, называется глобальной навигацией. Глобальная навигация может быть представлена несколькими способами, включая навигационные панели, выпадающие и раскрывающиеся меню. На одном и том же сайте глобальная навигация может отображаться по-разному, в зависимости от размера области просмотра.

Всегда следите за тем, чтобы пользователи могли перейти на любую страницу вашего сайта с помощью минимального количества щелчков мыши, а сама навигация была интуитивно понятной и не перегруженной. При этом особых требований к навигационным элементам не существует. MachineLearningWorkshop.com, будучи одностраничным сайтом, имеет локальную навигационную панель в правом верхнем углу; на многостраничных сайтах именно здесь часто размещается глобальная навигация.

Первая страница этой страницы, включая хлебные крошки в верхней части, кнопку, показывающую оглавление этой страницы, и локальные навигации для серии.

Если вы просматриваете эту страницу на web.dev, то можете заметить несколько особенностей навигации. Над заголовком находится хлебная крошка, после заголовка — оглавление "На этой странице", а также оглавление "Изучение HTML", которое в зависимости от ширины экрана либо отображается всегда, либо становится видимым при нажатии на кнопку меню. Первым элементом на странице является скрытая ссылка на #main, которая позволяет пропустить как боковую панель, так и ссылки на хлебные крошки.

Первый элемент на странице является внутренней ссылкой:

1
<a href="#main" class="skip-link button">Skip to main</a>

который при нажатии на него или при наличии фокуса и нажатии пользователем кнопки Enter прокручивает страницу и передает фокус основному содержимому: ориентиру <main> с id main:

1
<main id="main"></main>

Возможно, вы никогда не видели эту ссылку на сайте, даже если прочитали все предыдущие разделы. Она отображается только при наличии фокуса:

Skip to Main button.

Для повышения удобства использования и доступности важно дать пользователям возможность обходить блоки контента, которые повторяются на каждой странице. Ссылка на пропуск включается для того, чтобы пользователь, нажимающий при загрузке клавишу Tab, мог быстро перейти к основному содержанию сайта, избежав необходимости переходить по обширным ссылкам. На этой странице ссылка "пропустить" пропускает навигацию по боковым панелям разделов и хлебные крошки, переводя пользователя непосредственно к заголовку страницы.

Большинству дизайнеров не нравится, когда ссылка располагается в верхней части страницы. Можно скрыть ссылку от посторонних глаз, помня при этом, что когда ссылка окажется в фокусе, а это произойдет, когда пользователь клавиатуры перейдет по ссылке на страницу, ссылка должна быть видна всем пользователям. Скрывать содержимое в нефокусном и неактивном состоянии можно только с помощью селектора, аналогичного .visually-hidden:not(:focus):not(:active).

Текст ссылки гласит "перейти к основному". Это доступное имя ссылки. Это технический сайт, и пользователи, вероятно, знают, что означает слово "главная". Как и весь текст ссылки, доступное имя должно четко указывать, куда ведет ссылка. Целью ссылки должно быть начало основного содержания страницы. Чтобы проверить это, при загрузке страницы перейдите по вкладке к ссылке "Skip to main". Затем нажмите Enter, чтобы убедиться, что ссылка "переходит" к основному содержанию.

Оглавление

Ссылка skip-to-content прокручивает основное содержание. Первым элементом является заголовок <h1> с названием данного раздела. В данном случае <h1>Разметка навигации</h1>. За основным заголовком следует теглайн — краткое описание содержания данного учебника. Будет ли навигация по оглавлению идти до или после заголовка в кодовой базе, зависит от ширины вашего браузера.

На узких экранах оглавление скрывается за кнопкой "На этой странице", которая переключает видимость навигации.

На узких экранах оглавление скрывается за кнопкой "На этой странице", которая переключает видимость навигации.

На широких экранах оглавление всегда видно, а ссылка на текущий раздел выделена синим цветом.

На широких экранах оглавление всегда видно, а ссылка на текущий раздел выделена синим цветом.

Если ширина браузера превышает 80em, то оглавление в разметке располагается перед заголовком и выглядит следующим образом (имена классов удалены для упрощения разметки):

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
<nav aria-label="On this page">
    <div>On this page</div>
    <div>
        <ul>
            <li>
                <a href="#skip">Skip to content link</a>
            </li>
            <li>
                <a href="#toc">Table of contents</a>
            </li>
            <li>
                <a href="#bc">Page breadcrumbs</a>
            </li>
            <li>
                <a href="#ln">Local navigation</a>
            </li>
            <li>
                <a href="#global">Global navigation</a>
            </li>
        </ul>
    </div>
</nav>

Элемент <nav> лучше всего использовать для разделов навигации: он автоматически сообщает программе чтения с экрана и поисковой системе, что раздел имеет роль navigation, роль ориентира.

Включение атрибута aria-label дает краткое описание назначения навигации. В данном случае, поскольку значение атрибута является избыточным для текста, видимого на странице, предпочтительнее использовать aria-labelledby для ссылки на видимый текст.

Мы можем изменить несемантический <div> на абзац <p>, затем добавить id, чтобы на него можно было ссылаться. Затем мы используем aria-labelledby:

1
2
3
<nav aria-labelledby="tocTitle">
    <p id="tocTitle">On this page</p>
</nav>

Помимо сокращения избыточности, видимый текст переводится службами перевода, в то время как значения атрибутов могут и не переводиться. По возможности, если имеется текст, обеспечивающий адекватную метку, отдавайте предпочтение ему, а не тексту атрибута.

Эта навигация является оглавлением. Если вы хотите использовать aria-label, предоставьте эту информацию, а не повторяйте видимый текст:

1
2
3
<nav aria-label="Table of Contents">
    <p>On this page</p>
</nav>

При указании доступного имени элемента не следует указывать его название. Эту информацию предоставляют пользователю программы чтения с экрана. Например, при использовании элемента <nav> не следует включать слово "навигация"; эта информация включается при использовании семантических элементов.

Сами ссылки располагаются в виде неупорядоченного списка. Хотя они не обязательно должны быть вложены в список, использование списка позволяет пользователям программы чтения с экрана знать, сколько элементов списка, а значит, и ссылок, приходится на отдельный список в навигации.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
<nav aria-labelledby="tocTitle">
    <p id="tocTitle">On this page</p>
    <ul role="list">
        <li>
            <a href="#skip">Skip to content link</a>
        </li>
        <li>
            <a href="#toc">Table of contents</a>
        </li>
        <li>
            <a href="#bc">Page breadcrumbs</a>
        </li>
        <li>
            <a href="#ln">Local navigation</a>
        </li>
        <li>
            <a href="#global">Global navigation</a>
        </li>
    </ul>
</nav>

Если ширина браузера не превышает 80em, то виджет "На этой странице" располагается ниже заголовка и теглайна. Это достигается за счет включения двух навигационных компонентов таблицы содержания и скрытия одного или другого с помощью CSS display: none; на основе медиазапроса.

Включение двух одинаковых виджетов для отображения только одного из них является антипаттерном. Дополнительные байты незначительны. Скрытие HTML-содержимого от всех пользователей с помощью CSS display: none вполне уместно. Проблема заключается в том, что на широких экранах оглавление располагается перед #main, а на узких экранах оглавление вложено в #main. При использовании клавиатуры для перехода к содержимому на широком экране оглавление пропускается. Хотя пользователи привыкли к тому, что контент реагирует на изменения и меняет свое местоположение при смене устройства или увеличении размера шрифта, они не ожидают, что порядок вкладок при этом изменится. Макеты страниц должны быть доступными, предсказуемыми и последовательными на всем сайте. В данном случае расположение оглавления не является предсказуемым.

Хлебные крошки страницы

Хлебные крошки обеспечивают вторичную навигацию, помогая пользователям понять, где они находятся на сайте. Обычно они показывают иерархию URL текущего документа и местоположение текущей страницы в структуре сайта. Структура сайта с точки зрения пользователя может отличаться от файловой структуры на сервере. Это нормально. Пользователю не обязательно знать, как организованы ваши файлы, но он должен уметь ориентироваться в вашем содержимом.

Хлебные крошки помогают пользователям ориентироваться и понимать организацию сайта, позволяя им быстро переходить к любым разделам-предшественникам без необходимости возвращаться на каждую предыдущую страницу, чтобы попасть на текущую, используя функцию back.

Если сайт имеет простую иерархическую структуру каталогов, как это имеет место в web.dev, то навигация по хлебным крошкам часто состоит из ссылки на home, или имя хоста, со ссылкой на индексный файл каждого каталога в имени пути URL. Включение текущей страницы является необязательным и требует некоторого дополнительного внимания.

1
2
3
4
5
const url = new URL(
    'https://web.dev/learn/html/navigation'
);
const sections = url.hostname + url.pathname.split('/');
// "web.dev,learn,html,navigation"

Секции хлебной крошки показывают путь от текущей страницы обратно к главной странице, отображая каждый уровень между ними.

Хлебные крошки, указывающие путь к текущей странице.

Каждая страница модуля Learn HTML имеет одинаковую навигационную хлебную крошку, отображающую иерархию уроков HTML в секции learn раздела web.dev. Код аналогичен приведенному ниже, но для наглядности удалены классы и детали SVG:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
<nav aria-label="breadcrumbs">
    <ul role="list">
        <li>
            <a href="/">
                <svg aria-label="web.dev" role="img">
                    <use href="#webDevLogo" />
                </svg>
            </a>
        </li>
        <li>
            <a href="/learn/">Learn</a>
        </li>
        <li>
            <a href="/learn/html">Learn HTML!</a>
        </li>
    </ul>
    <share-action
        authors="@estellevw"
        data-action="click"
        data-category="web.dev"
        data-icon="share"
        data-label="share, twitter"
        role="button"
        tabindex="0"
    >
        <svg aria-label="share" role="img">
            <use href="#shareIcon" />
        </svg>
        <span>Share</span>
    </share-action>
</nav>

Эта хлебная крошка соответствует лучшим практикам. В ней используется элемент <nav>, играющий роль ориентира, поэтому вспомогательные технологии представляют хлебные крошки как навигационный элемент на странице. Доступное имя "хлебные крошки", снабженное меткой aria-label, отличает их от других навигационных ориентиров в текущем документе.

Между ссылками располагаются CSS-генерируемые разделители содержимого. Разделители располагаются перед каждым элементом списка, начиная со второго <li>.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
[aria-label^='breadcrumb' i] li + li::before {
    content: '';
    display: block;
    width: 8px;
    height: 8px;
    border-top: 2px solid currentColor;
    border-right: 2px solid currentColor;
    rotate: 45deg;
    opacity: 0.8;
}

Программы чтения с экрана не будут их "видеть", что является наилучшей практикой: разделители между ссылками хлебных крошек должны быть скрыты от программ чтения с экрана. Кроме того, они должны быть достаточно контрастными по отношению к фону, как и обычный текст.

В данной версии используется неупорядоченный список и элементы списка. Упорядоченный список предпочтительнее, так как элементы упорядоченного списка перечисляются. Кроме того, это список: role="list" было добавлено, поскольку некоторые значения свойства отображения CSS лишают семантики некоторые элементы.

Вообще, ссылка на главную страницу в хлебной крошке должна иметь значение "home", а не быть логотипом сайта с названием сайта в качестве метки. Но поскольку хлебная крошка находится в верхней части документа и является единственным появлением логотипа на странице, то становится понятно, почему был использован этот антипаттерн.

Последний элемент — это пользовательский элемент <share-action>. Пользовательские элементы рассматриваются далее. Хотя этот пользовательский элемент не является частью хлебной крошки, включение несвязанного элемента в <nav> вполне допустимо, если это включение единообразно на всех страницах.

Текущая страница

На этой странице текущая страница "Навигация" не включена в хлебную крошку. Когда текущая страница включается в хлебную крошку, текст предпочтительно не должен быть ссылкой, а aria-current="page" должен быть включен в элемент списка текущей страницы. В тех случаях, когда он не включен, полезно указать на то, что следующий за ним заголовок является текущей страницей, с помощью пиктограммы или другого символа.

При изменении дизайна можно использовать альтернативный вариант хлебной крошки:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
<nav aria-label="breadcrumbs">
    <ol role="list">
        <li>
            <a href="/">Home</a>
        </li>
        <li>
            <a href="/learn/">Learn</a>
        </li>
        <li>
            <a href="/learn/html">Learn HTML!</a>
        </li>
        <li aria-current="page">Navigation</li>
    </ol>
</nav>

Хлебные крошки не предназначены для линейных шагов. Например, список путей, по которым пользователь перешел на текущую страницу, или список шагов, пройденных до этого момента в рецепте, может быть вложен в <nav>, но не должен обозначаться как хлебная крошка.

Локальная навигация

На этой странице есть еще один навигационный компонент. Если вы находитесь на широком экране, то слева расположена боковая панель с логотипом "Learn HTML", строкой поиска и ссылками на каждый из 20 разделов "Learn HTML". Каждая ссылка содержит номер главы, название раздела и галочку справа от разделов, которые вы уже посещали — возможно, этот раздел, если вы переходили от него и вернулись. Ссылки на все разделы в Learn HTML, а также на поиск и локальный заголовок являются навигацией по сайту.

Если вы посещаете этот сайт на планшетном или мобильном устройстве или имеете более узкий экран, то при загрузке этой страницы боковая панель будет скрыта. Сделать ее видимой можно с помощью гамбургер-меню в верхней панели навигации (да, заголовок — это пользовательский элемент <web-header> с установленной ролью="navigation").

Основное отличие постоянной локальной навигации на широких экранах от локальной навигации на более узких экранах, которую можно сделать появляющейся и исчезающей, заключается в отображении кнопки закрытия на версии, которую можно скрыть. На широких экранах этот значок скрывается с помощью display: none;.

В локальной навигации рядом с названием этой главы стоит галочка.

Ссылка на данный документ, раздел 010, имеет несколько иной вид, чем другие ссылки в локальной навигации, чтобы указать зрячим пользователям, что это текущая страница. Это визуальное отличие создается с помощью CSS. Текущая страница также идентифицируется с помощью атрибута aria-current="page". Это информирует вспомогательные технологии о том, что это ссылка на текущую страницу. HTML для этого элемента списка в рамках локальной навигации выглядит следующим образом:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
<li>
    <a
        aria-current="page"
        href="/learn/html/navigation/"
        data-complete="true"
    >
        <span>010</span>
        <span>Navigation</span>
        <svg aria-label="Check" role="img">
            <use href="#checkmark" />
        </svg>
    </a>
</li>

Если вы посещаете эту страницу не в первый раз, то галочка не будет видна. Если вы посещали эту страницу в прошлом, то для data-complete пользовательского атрибута установлено значение true, и флажок будет отображаться. Флажок включен в каждую ссылку, но CSS скрывает его от пользователей, не посещавших эту страницу ранее, с помощью display: none, основываясь на отсутствии атрибута data-complete="true" и его значения:

1
2
3
.course .stack-nav a:not([data-complete='true']) svg {
    display: none;
}

Когда display имеет значение, отличное от none, role сообщает вспомогательным технологиям, что инлайн SVG является изображением, а aria-label действует как атрибут alt в <img>.

Глобальная навигация

Глобальная навигация — это раздел навигации, ведущий к страницам верхнего уровня сайта, который одинаков на всех страницах сайта. Глобальная навигация сайта может также состоять из вкладок, открывающих вложенные списки ссылок на все подразделы сайта, или других меню. Она может включать в себя заголовки разделов, кнопки и виджеты поиска. Эти дополнительные возможности не являются обязательным условием. Требуется, чтобы навигация отображалась на каждой странице и была одинаковой на всех страницах; разумеется, с указанием aria-current="page" для всех ссылок на текущую страницу.

Глобальная навигация обеспечивает последовательное перемещение в любой точке приложения или сайта. У Google нет глобальной навигации в верхней части страницы. У Yahoo! она есть. Хотя все основные свойства Yahoo! имеют различные стили, содержание большинства разделов одинаково.

A well-contrasted navigation header, with a white picker on a black background.


A poorly-contrasted navigation header, with a black picker on a grey background.

Содержание заголовков глобальной навигации в разделах "Новости" и "Спорт" одинаково, но пиктограмма, показывающая, что пользователь находится в разделе "Спорт", недостаточно контрастна, чтобы быть доступной даже для посетителей, не имеющих слабого зрения. В обоих разделах имеется глобальная навигация, под которой располагается локальная навигация по конкретным разделам.

Как и глобальная навигация, нижние колонтитулы должны быть одинаковыми на всех страницах. Но это единственное сходство. Глобальная навигация позволяет ориентироваться во всех разделах сайта с точки зрения продукта. К элементам навигации в нижнем колонтитуле не предъявляется особых требований. Как правило, нижний колонтитул содержит корпоративные ссылки, такие как юридическая информация, информация о компании, карьера, и может вести на внешние источники, например, на значки социальных сетей.

Нижний колонтитул этой страницы содержит три дополнительных элемента <nav>: навигация по нижнему колонтитулу, разработчики Google и условия и политика, причем каждый из них является ссылкой. Навигация в нижнем колонтитуле включает в себя информацию о том, как внести вклад в web.dev на Github, другие образовательные материалы, предоставляемые Google за пределами web.dev, и внешние ссылки "как подключиться".

Эти три навигации в <footer> являются элементами <nav> с меткой aria-label, предоставляющей доступное имя для этих знаковых ролей. Все рассмотренные нами навигации представляют собой ссылки, вложенные в списки внутри навигации. Мы рассмотрели все, что необходимо знать для создания собственных навигаций. Далее мы рассмотрим разметку таблиц данных.

Источники

Комментарии