导航

正如您在链接中了解到的,带有 href 属性的 <a> 元素会创建链接,用户可以通过点击或点按来访问这些链接。在列表中,您了解了如何创建内容列表。在本模块中,您将了解如何将链接列表分组在一起以创建导航。

导航有多种类型,显示方式也有多种。文本中链接到同一网站内其他网页的命名锚点被视为本地导航。本地导航由一系列链接组成,用于显示当前网页相对于网站结构的层次结构,或用户为到达当前网页而访问的网页,称为面包屑。

网页的目录是另一种类型的本地导航。包含指向网站上每个网页的层次结构链接的网页称为站点地图。指向网站顶级页面的导航(可能位于每个页面上)称为全局导航。全局导航可以采用多种不同的方式显示,包括导航栏、下拉菜单和飞出式菜单。同一网站可能会根据视口大小以不同的方式显示其全局导航。

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

“学习 HTML”的“导航”模块。
如果您在 web.dev 上访问此页面,会发现一些导航功能。标题上方有一个面包屑导航,其中包含“学习 HTML”目录,并且根据屏幕宽度,还包含“本页内容”目录。

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

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

当用户点击此链接或此链接获得焦点且用户按下 Enter 时,页面会滚动,并将焦点移至具有 main ID 的元素(可能是主要内容)。

<main id="main">

为了提高易用性和无障碍性,请务必让用户能够绕过每个网页上重复出现的内容块,例如共享标题和主要导航项。借助跳转链接,键盘用户在按下 tab 后,可以快速前往页面上的新内容。这样,他们就无需在庞大的菜单中逐个标签页进行浏览。

大多数设计师都不喜欢在页面顶部显示此类链接。您可以放心地隐藏该链接。不过,请注意,当链接获得焦点时(即键盘用户在网页上通过 Tab 键切换到该链接时),该链接必须对用户可见。

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

与所有链接文字一样,名称应明确指示链接会将用户引导至何处。链接目标应为网页主要内容的开头。

目录

主要内容的第一个元素是 <h1> 标题,其中包含此页面的标题:<h1>Navigation</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>

避免更改标签页顺序

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

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

虽然用户已经习惯了内容在更改设备或增大字号时会自适应地调整位置,但他们不希望标签页顺序也随之发生变化。网页布局应在整个网站中保持一致,并且易于访问和预测。在这种情况下,目录的位置是不可预测的。

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

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

面包屑可让用户了解您网站的结构。这有助于用户使用 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 display 属性值会移除某些元素的语义。

一般来说,面包屑导航中的首页链接应显示为“首页”,而不是网站名称或网站徽标。由于面包屑位于文档顶部,因此可以理解为何使用此反模式。

当前页面(即导航)未包含在面包屑中。

当前页面

如果当前网页包含在面包屑中,则相应文字最好不是链接,并且当前网页的列表项中应包含 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>
正确!

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

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