导航

正如您在 links 中所学到的,具有 href 属性的 <a> 元素会创建用户可以点击或点按的链接。在列表部分,您学习了如何创建内容列表。在本单元中,您将了解如何将链接列表分组以创建导航栏。

导航元素分为多种类型,它们的显示方式也有多种。文本中链接到同一网站中的其他网页的命名锚标记会被视为本地导航。本地导航由一系列链接组成,用于显示当前网页相对于网站结构的层次结构,或用户访问当前网页时所经的网页,称为面包屑导航。

网页的目录是另一种类型的本地导航。包含指向网站上每个网页的分层链接的网页称为网站地图。指向网站顶级页面的导航栏(可能位于每个网页上)称为全局导航栏。全局导航栏可以通过多种不同的方式显示,包括导航栏、下拉菜单和弹出式菜单。同一网站的全局导航栏的显示方式可能会因视口大小而异。

请始终确保用户只需点击最少的次数即可前往您网站上的任何页面,同时确保导航直观且不会让用户感到不知所措。不过,导航元素没有特定要求。MachineLearningWorkshop.com 是一个单页网站,在右上角有一个本地导航栏;多页网站通常会将全局导航栏放置在此处。

“了解 HTML”的导航模块。
如果您在 web.dev 上访问此页面,会发现一些导航功能。标题上方有一个面包屑导航栏,还有一个“学习 HTML”目录,以及一个“本页内容”目录(具体取决于屏幕的宽度)。

有些网站会提供“跳转至内容”链接,该链接通常是焦点顺序中的第一个元素。代码可能如下所示:

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

当用户点击该元素或该元素获得焦点且用户按 Enter 时,该元素会滚动网页并将焦点移至 ID 为 main 的元素(可能是主要内容)。

<main id="main">

为了提高易用性和无障碍性,请务必让用户能够跳过每个网页上重复的内容块,例如共享标题和主要导航项。借助跳过链接,当键盘用户点击 tab 时,他们可以快速转到页面上的新内容。这样一来,用户就不必在内容丰富的菜单中执行 Tab 键操作。

大多数设计师都不喜欢在页面顶部显示此类链接。您可以将该链接隐藏起来。不过,请注意,当链接获得焦点时(键盘用户通过 Tab 键浏览页面上的链接时),链接必须对用户可见。

使用与 .visually-hidden:not(:focus):not(:active) 类似的选择器,仅在非聚焦和非活跃状态下隐藏内容。

与所有链接文字一样,名称应清楚地指明链接会将用户定向到何处。链接目标应是网页主要内容的开头。

目录

主内容的第一个元素是包含此页面标题 <h1>Navigation</h1><h1> 标题。主标题后面是对本教程内容的简要说明。

本页目录。
目录始终可见。

在较小的屏幕上,目录会显示在标题后面。在较大的屏幕上,该标签页会显示在右对齐的边栏中。

最适合用于导航部分的元素是 <nav>。它会自动告知屏幕阅读器和搜索引擎,某个版块的角色为 navigation(地图注点角色)。

添加 aria-label 属性,以简要说明导航栏的用途。在本例中,由于该属性的值与“在此页面上”文本重复,如需引用可见文本,请改用 aria-labelledby

使用 id,可能如下所示:

<nav aria-labelledby="tocTitle">
  <p id="tocTitle">On this page</p>
...
</nav>

除了减少冗余之外,可见文本还会由翻译服务进行翻译,而属性值可能不会。如果存在可提供适当标签的文本,请尽可能引用该文本,而不是使用属性文本。

“在此页面上”导航栏是目录。如果您想使用 aria-label,请提供该上下文,而不是重复可见文本:

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

如需为元素提供无障碍名称,请不要添加元素的名称。屏幕阅读器会向用户提供元素的名称。例如,使用 <nav> 元素时,请勿添加“导航”一词,因为该信息已包含在语义元素中。

虽然导航项不必嵌套在列表中,但使用列表可让屏幕阅读器用户知道导航栏中有多少列表项(即链接)。

<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>

避免更改 Tab 键顺序

目录可能会显示在标题后面、较小的屏幕上,或在右对齐的边栏中。包含两组完全相同的导航栏,但只显示其中一个,这是一种反模式。

我们使用 CSS 在宽度超过 1254px 的网页上将导航栏显示为边栏。

虽然用户已习惯内容在更换设备或增大字号时自适应并更改位置,但他们不希望在执行这些操作时标签页顺序也随之更改。网页布局应在整个网站中保持可访问、可预测且一致。在这里,目录的位置不可预测。

面包屑导航提供次级导航,有助于用户了解自己在网站上的所在位置。面包屑导航通常会指明当前文档的网址层次结构以及当前网页在网站结构中的位置。

用户视角的网站结构可能与服务器上的文件结构不同,这也没有关系。用户无需了解您如何整理文件,但需要能够浏览您的内容。

面包屑导航可让用户深入了解您网站的组织结构。这有助于用户导航到任何祖先部分,而无需使用 back 函数返回之前访问过的每个页面。

如果网站采用分层目录结构(如 web.dev),面包屑导航栏通常包含指向首页或主机名的链接,以及指向网址路径中每个目录的索引文件的链接。包含当前页面是可选操作,需要额外注意一些。

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

面包屑导航的各个部分会显示从当前网页返回到首页的路径,并显示中间的每个层级。

指示导航页路径的路径。

每个“学习 HTML”模块页面都有相同的面包屑导航栏,在 web.devLearn 部分中显示 HTML 课程的层次结构。

代码应类似于以下内容:

<nav aria-label="breadcrumbs">
  <ol role="list">
    <li>
      <a href="/">web.dev</a>
    </li>
    <li>
      <a href="/learn">Learn</a>
    </li>
    <li>
      <a href="/learn/html">HTML</a>
    </li>
  </ol>
</nav>

<nav> 元素(一种地图注点角色)会告知辅助技术将面包屑导航作为网页上的导航元素呈现。通过 aria-label 提供的“面包屑导航”的无障碍名称可将此导航与同一文档中的其他导航地图注点区分开来。

每个链接之间都有一个内容分隔符。这些分隔符可以使用 CSS 生成,以便在每个列表项(从第二个列表项开始)之前显示。

[aria-label^="breadcrumbs" i] li + li::before {
  content: "";
  display: block;
  width: 8px;
  height: 8px;
  border-top: 2px solid currentColor;
  border-right: 2px solid currentColor;
  rotate: 45deg;
  opacity: .8
}

屏幕阅读器不会“看到”这些图标,这是最佳实践。面向屏幕阅读器应隐藏面包屑链接之间的分隔符。它们还必须与背景形成足够鲜明的对比效果,就像页面上的任何其他文本和视觉元素一样。

我们的示例代码使用有序列表,因为它会枚举项,因此优于无序列表。添加 role="list" 是因为某些 CSS 显示属性值会移除某些元素的语义。

通常,面包屑导航中指向首页的链接应为“首页”,而不是网站名称或网站徽标。由于面包屑导航位于文档顶部,因此使用此反模式是合理的。

面包屑导航中未包含当前网页“导航”。

当前页面

当当前网页包含在面包屑导航中时,文本最好不是链接,并且当前网页的列表项中应包含 aria-current="page"。如果未添加此属性,最好指明其后面的标题为带有图标或其他符号的当前页面。

我们来看看采用此做法的面包屑导航栏的另一种版本:

<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> 中,但不应标记为面包屑导航。

本地导航

了解 HTML 章节导航。

在大多数中等大小和更大的设备上,下一个导航组件会显示在左侧边栏中,其中包含一个过滤栏和指向“学习 HTML”中的各个部分的链接。这些链接和过滤栏就是位置导航栏。

如果您使用移动设备访问此网站,或者屏幕较窄,则在加载此页面时,侧边栏会隐藏。您可以使用顶部导航栏中的 访问它。

宽屏幕上的永久性本地导航栏与窄屏幕上的本地导航栏之间的主要区别在于,箭头会返回到主顶部导航栏,然后关闭导航栏。

指向此文档的链接与本地导航栏中的其他链接看起来一样。不过,它的外观可能与其他链接略有不同,以便告知视力正常的用户这是当前网页。此视觉差异应使用 CSS 创建。

您还可以使用 aria-current="page" 属性来识别当前网页。这会告知辅助技术,链接指向当前网页。

理想情况下,本地导航栏中此列表项的 HTML 应如下所示:

<li>
  <a aria-current="page" aria-selected="true" href="/learn/html/navigation">
    Navigation
  </a>
</li>

全局导航指向网站的顶级页面,网站的每个页面都一样。网站的全局导航栏还可以由标签页组成,这些标签页会打开链接的嵌套列表,这些链接会指向网站的所有子部分或其他菜单。它可能包含标题部分、按钮和搜索 widget。这些附加功能并非强制性要求。所需的导航栏必须显示在每个网页上,并且每个网页上的导航栏都相同,当然,指向当前网页的所有链接都必须带有 aria-current="page"

全局导航可提供一致的方式,让用户在应用或网站中的任意位置导航。Google 网站的网页顶部没有全局导航栏。Yahoo! 做到了。虽然所有主要的 Yahoo! 媒体资源都有不同的样式,但大多数版块的内容是相同的。

导航标题的对比度较差。
Yahoo! 导航栏,其中包含灰色背景上的黑色选择器。

新闻和体育类全球导航标头的内容相同。 不过,显示用户位于体育页面的图标对比度不够,无法访问,即使是视力正常的访问者也无法访问。这两个版块都有全局导航栏,下方是特定于版块的本地导航栏。

对比度较高的导航栏,黑色背景上有白色选择器。
下面是颜色对比度更高的改进版导航栏。

与全局导航栏类似,所有网页的页脚都应保持一致。但这是唯一的相似之处借助全局导航,您可以从商品的角度导航到网站的所有部分。页脚中的导航元素没有特定要求。

通常,页脚包含公司链接,例如法律声明、公司简介、职业页面,以及指向社交媒体等相关外部来源的链接。

此页面的页脚包含两组导航元素:一组包含三个列的相关 web.dev 导航,以及一组单独的 Google 条款和隐私权导航。页脚导航栏包含如何为 web.dev 贡献内容、web.dev 团队提供的相关内容,以及外部社交媒体链接。

接下来,我们将介绍如何标记数据表。

检查您的理解情况

测试您对导航栏的知识掌握情况。

哪个元素用于标记网站的主导航栏?

<navigation>
请重试。
<breadcrumb>
请重试。
<nav>
正确!

一个网页上可以有多个导航元素吗?

错误。
请重试。
正确。
正确!