单独使用无效,因其仅为语义容器而非用途说明书;多个必须用aria-label明确区分功能,如“主导航”“面包屑导航”,否则屏幕阅读器仅报“导航区域”后静默跳过。

只套 <nav></nav> 标签不加 aria-label,屏幕阅读器基本等于没看见这个导航区域。
为什么 <nav></nav> 单独写没用
浏览器和 NVDA、VoiceOver 这类辅助技术会把 <nav></nav> 当作一个语义容器,但不会自动告诉你“这是主导航”还是“这是页脚快捷入口”。当页面里有多个 <nav></nav>(比如顶部菜单 + 面包屑 + 页脚链接),读屏器只报“导航区域”,然后静默跳过——用户得手动 Tab 摸索,根本不知道哪个是该用的。
常见错误包括:
-
<nav aria-label="Navigation"></nav>—— 所有导航都叫 Navigation,等于没标 -
<nav></nav>完全没加aria-label—— NVDA 默认播报“导航区域”,不读内容也不提示用途 -
<nav></nav>套在<div onclick=""> 里 —— 事件冒泡中断、移动端热区被裁切、键盘焦点错位 <h3> <code><nav></nav>里该用什么结构才对导航的本质是一组可顺序访问的跳转目标,不是视觉盒子。不能靠
<div> 堆砌链接,也不能用 <code><ul></ul>却不配语义化标签。立即学习“前端免费学习笔记(深入)”;
DeepBI DHTML 页面生成器下载生成可在 deepbi 沙箱 iframe 内运行或作为独立文件运行的交互式 HTML 页面,使用 `window.deepbi` JS SDK 实现数据查询、空间管理、文件浏览及用户操作。当用户提出以下需求时启用该能力: - 创建 KPI 仪表盘、数据表格、文件浏览器、成员列表、管理页面; - 明确要求“转成 dhtml”、“转译成 HTML”、“把 XX 页面转成……”、“控制台页面”、“管理后台”、“DeepBI 页面迁移”; - 提及位于 `apps/console/src/featur
- 必须用
<ul></ul>或<ol></ol>包裹链接,<ol></ol>更适合有明确顺序的场景(如面包屑、步骤条),读屏器会读出“第1项”“第2项” - 禁用
role="list"或role="navigation"套在<ul></ul>上——重复声明反而干扰默认行为 - 每个链接必须是
<a></a>或<button></button>,不能是<span></span>+onclick模拟,否则键盘无法聚焦、回车不触发
当前页链接怎么标才不翻车
“当前页”不是“禁用按钮”,而是语义终点。用
aria-disabled="true"或删掉href是典型误用,会导致键盘用户卡住、读屏器跳过或误报“已禁用”。- 必须保留
href(哪怕指向当前 URL),确保可聚焦、可回车触发(JS 可拦截) - 当前页链接加
aria-current="page",仅此一项,值只能是"page",不能是"true"或"active" - 不要给整个
<nav></nav>加aria-current,它只作用于具体<a></a>元素 - 禁用状态(如灰掉的“下一页”)要用
disabled属性(<button disabled></button>)或aria-disabled="true"+tabindex="-1",并同步视觉样式
嵌入式链接要不要套
<nav></nav>不是所有带链接的区域都该用
<nav></nav>。关键看它是否构成独立导航上下文。- 卡片里的“编辑|删除|预览”属于控件组,用
<div role="group" aria-label="文章操作"> 更准确 <li>页内锚点跳转列表(如目录树)可以是 <code><nav aria-label="页内目录"></nav> - 登录/注册链接、相关阅读、分享按钮这些不属于导航意图,别硬塞进
<nav></nav>,否则 AT 用户按 N 键会跳进一堆无关链接
最常被忽略的一点:多个
<nav></nav>必须各自有不可混淆的aria-label值,且不能依赖 JS 动态注入——初始 HTML 就得写对,否则 SSR 或旧版读屏器直接失效。 - 必须用


















