Menu

HTML nav 标签:导航栏、菜单与面包屑

<nav> 元素用来标记一组主要的导航链接。学习如何用 <nav> 和列表搭建导航栏,如何标记当前页面,如何为同一页面上的多个 nav 添加标签,以及如何制作移动端菜单开关。

本页包含可运行的编辑器。编辑、运行,立即查看输出。

用 nav 搭建导航栏

把菜单包裹在 <nav> 中,再把链接放进列表。Flexbox 会把列表变成一条横向的导航栏:

list-style: none 和 padding: 0 去掉了项目符号和缩进。给每个链接设置 display: block,让它的内边距在导航栏中占据真实的空间,这样整个带内边距的区域都可以点击。删掉 display: flex 那一行,同一个菜单就会变成竖向列表,侧边栏菜单就是这个样子。

<nav> 本身没有任何外观。它的作用是表达含义:屏幕阅读器会把它作为导航地标呈现,用户按一个键就能跳到菜单,或者跳过它。

标记当前页面

给当前显示页面的链接加上 aria-current="page"。它会告诉屏幕阅读器“你在这里”,也给了 CSS 一个用来高亮链接的钩子:

把 aria-current="page" 移到另一个链接上,高亮也会跟着移动。为这个属性设置样式,而不是用 .active 类,可以让外观和无障碍保持同步:有了其中一个,就一定有另一个。

一个页面上的多个 nav:标签与面包屑

一个页面可以有主菜单、面包屑和目录,每个都放在自己的 <nav> 中。给每个 nav 设置 aria-label,这样屏幕阅读器会读出“Breadcrumb 导航”,而不是三个一模一样的“导航”:

面包屑使用有序列表 <ol>,因为顺序很重要。斜杠来自 CSS 的 ::before,所以屏幕阅读器不会在每一项之间读出“斜杠”。最后一项是当前页面,不是链接。

目录

指向同一页面各个部分的链接列表也是导航。#id 链接会跳转到带有该 id 的元素;在预览中试试:

这里的标签来自一个可见的标题,通过 aria-labelledby 关联;当标题已经显示在屏幕上时,这比 aria-label 更好。

移动端菜单开关

在窄屏幕上,菜单通常隐藏在一个按钮后面。使用真正的 <button> 并加上 aria-expanded,链接仍然放在 <nav> 中:

aria-expanded 告诉屏幕阅读器菜单是否已展开,而 hidden 属性会在菜单收起时把列表从屏幕和无障碍树中一并移除。在宽屏幕上,你可以用媒体查询显示列表并隐藏按钮。

常见错误

  • 把每一组链接都包进 <nav>。 它用于主菜单、面包屑、分页和目录。正文中的行内链接不是导航区块。
  • 用 <div> 做菜单按钮。 它无法用键盘聚焦或按下。请使用 <button>。
  • 多个 nav 都没有标签。 给每个 nav 加上 aria-label 或 aria-labelledby,以便区分。
  • 只给当前链接换个颜色。 加上 aria-current="page";单靠颜色不会被读出来,也不是每个人都能看出来。
  • 正式上线的页面中使用 href="#" 的链接。 在演示中没问题,但真正的菜单项需要真实的 URL,在新标签页中打开时才能正常工作。链接一页介绍了 href 的各种取值。

常见问题

HTML 中的 nav 标签是什么?

<nav> 是一个语义元素,用来包裹一组主要的导航链接,比如网站菜单、目录或面包屑。屏幕阅读器会把它列为导航地标,用户可以直接跳转到那里。

nav 里面的链接应该放在列表中吗?

这是常见的做法,也是好的做法:由 <li> 项组成的 <ul> 能让屏幕阅读器报出菜单中有多少个链接。直接把链接放在 <nav> 中也是有效的,比如一行只有两三个链接的时候。

每一组链接都需要 nav 元素吗?

不需要。<nav> 只用于主要的导航区块。段落中的几个链接、页脚中简短的法律链接列表都不需要它,导航地标太多反而会让每一个都更难找到。

如何制作横向导航栏?

把链接放进 <nav> 中的 <ul>,然后给列表设置 display: flex; list-style: none; padding: 0; 和一个 gap。Flexbox 会把各项排成一行。

如何在导航栏中显示当前页面?

给用户所在页面的链接加上 aria-current="page",并用选择器 [aria-current="page"] 为它设置样式。这样屏幕阅读器也会把它读作当前页面。

一个页面可以有多个 nav 吗?

可以,比如主菜单、面包屑路径和目录。给每个 nav 设置不同的 aria-label,比如“Main”或“Breadcrumb”,让使用屏幕阅读器的用户能够区分它们。

Coddy 编程语言插图

和 Coddy 一起学编程

开始