<nav> 的作用是明确标识导航区域的语义,供辅助技术识别并提升可访问性与SEO;必须包裹纯跳转链接,排除logo等非导航元素,且需配合正确href、<ul>结构及aria-current="page"实现完整无障碍支持。
<nav> 的作用不是“让导航看起来更整齐”,而是告诉浏览器、搜索引擎和屏幕阅读器:“这一块是专门用来跳转的,别当普通内容处理”。没它,链接照样能点;有了它,键盘用户能按 Insert+F7 一键跳到导航区,SEO 也能更准识别主路径。
常见错误是把 logo、搜索框、语言切换器一股脑塞进 <nav>。但 <nav> 只管“跳转目的地”,不管“辅助功能组件”。比如:
<header> 里,<nav> 只包 <ul> 或一组 <a>
<nav><div class="logo">...</div><ul>...</ul></nav> —— logo 不是导航项,不该混在里面<nav><a href="#top">回到顶部</a></nav>,语义不能省链接失效往往不是代码写错,而是 href 值没匹配部署环境或交互预期:
href="about.html")或根相对路径(如 href="/contact"),避免 href="#" + JS 拦截 —— 这会让右键“在新标签页打开”失效,且对键盘用户不友好href="https://example.com",不能只写 href="example.com",否则会当成当前域下的子路径href="#section1",但若导航栏是 position: fixed,需额外加 scroll-margin-top 防止目标被遮挡href="mailto:[email protected]",别漏 mailto: 前缀不是因为“好看”,而是因为语义和可访问性刚性要求:
立即学习“前端免费学习笔记(深入)”;
<ul> 表示“一组并列的导航项”,读屏器会报“列表,共 4 项”,用户能快速感知结构规模;平铺 <a> 则只能逐个读出,失去上下文<ul> 和平铺 <a> 渲染效果一致,但 <ul><li><a> 是唯一被所有主流读屏器稳定支持的模式<nav><a></a></nav>,但别为了省两行标签牺牲语义静态 HTML 无法自动高亮当前页,但不标记会导致键盘用户无法分辨“我现在在哪”。硬编码 class="active" 会误导读屏器(它只认语义属性,不认 class):
aria-current="page",例如首页是 <a href="/" aria-current="page">首页</a>
a[aria-current="page"] { font-weight: bold; color: #007BFF; } 控制样式,比依赖 JS 更稳window.location.pathname 也可行,但要防 FOUC(闪动)和路由异步加载延迟role="navigation" 替代 <nav> —— 它只是降级兜底,不能取代原生语义标签真正难的不是写出能显示的导航,是让它在盲人用户用 VoiceOver 滑动时有明确层级,在手机上拇指点得中,在 Chrome DevTools 模拟 320px 宽度时不溢出,在打印 PDF 时仍保持逻辑顺序——这些都藏在 <nav> 的边界定义、href 的路径选择和 aria-current 的精准标注里。