<nav> 标签是强制语义要求,不用则读屏器不识别导航区域、键盘无法跳转、搜索引擎降权;必须用真实 href、正确结构、可访问交互设计。

nav 标签不是可选,是强制语义要求
不用 <nav>,读屏器就当那段是普通段落,不会提示“导航区域”,键盘用户按 Ctrl+Alt+Insert+N(NVDA)或 D(JAWS)根本跳不过去。搜索引擎也会降权处理——这不是“更好看”,而是“能不能被正确识别”的问题。
常见错误现象:<div class="nav"><a>首页</a></div> —— 读屏器播报“首页”,没上下文;<nav><button>产品</button></nav> —— 按钮不是导航链接,无法被 Tab 焦点自然捕获,也不支持右键“在新标签页打开”。
- 每个页面最多 2–3 个
<nav>:顶部主菜单、页脚快捷链接、面包屑(后者必须加aria-label="当前位置") - 子菜单用
<ul>+<li>,别嵌套<nav>;纯图标按钮(如☰)必须配aria-label="打开菜单" - 移动端汉堡菜单的
<input type="checkbox">要和<label>严格绑定for属性,否则触控焦点无法激活
a 标签必须真实可达,href 不能是空字符串或 javascript:void(0)
很多“高亮失效”问题,根源是 <a href=""> 或 <a href="javascript:void(0)">。浏览器不认为这是有效链接,:hover、:focus、:visited 伪类全失效,键盘 Enter 也无法触发,读屏器还会报“空链接”警告。
正确做法:静态页面就写真实路径,比如 href="/about" 或 href="about.html";单页应用(SPA)必须配合 JS 使用 history.pushState(),且需监听 popstate 事件同步 UI 状态。
立即学习“前端免费学习笔记(深入)”;
-
href="#"只能用于锚点跳转(如href="#contact"),且目标元素必须有id="contact" - Safari 对
a:hover有严格限制:若没定义a:link和a:visited的基础样式(如color、text-decoration),background-color或transform在 hover 时会被忽略 - 点击热区必须 ≥44×44px:给
a加display: block+padding,别只靠文字撑开
当前页高亮必须手动控制 class,别等 JS 自动加
纯 HTML/CSS 导航栏里,“当前页高亮”不是自动发生的。浏览器不会根据 URL 自动给某个 <a> 加 class="active"——那是 JS 框架或后端模板做的事。你得在每个页面里,手工把对应链接加上 class="active",再用 CSS 控制样式。
错误示范:<a href="/blog">博客</a> 在 /blog 页面里还是没 class;或者用 JS 动态判断 window.location.pathname 再加 class,但 JS 加载失败时整个高亮逻辑就崩了。
- 推荐写法:
<a href="/blog" class="active">博客</a>(仅在/blog页面中出现) - CSS 写
a.active { background-color: #007bff; color: white; },别只写.active,避免样式污染其他元素 - 如果导航项是多级(如 Element Plus 的
.el-submenu),上级菜单高亮需额外加::v-deep(.el-submenu.is-active > .el-submenu__title)这类穿透选择器
移动端折叠菜单必须用 :checked + ~ 选择器,而非 JS 切 class
依赖 JS 控制汉堡菜单显隐,一旦脚本加载失败或被拦截,菜单就完全不可用。CSS-only 方案用 <input type="checkbox" id="menu-toggle"> + <label for="menu-toggle"> + :checked ~ 选择器,更可靠、更轻量、也更符合渐进增强原则。
关键细节:下拉菜单 <ul> 必须用 position: absolute 或 top: 100% 脱离文档流,否则展开时会撑开页面导致布局跳动;overflow: hidden 配合 max-height 做展开动画比 display: none/block 更平滑。
- 别漏掉
<meta name="viewport" content="width=device-width, initial-scale=1">,否则媒体查询在 iOS 上直接失效 -
label必须用for显式关联input,不能靠 DOM 顺序或 JS 绑定 - 键盘用户需要
tabindex="0"和role="button"支持,否则Space/Enter无法触发 checkbox
最容易被忽略的是:所有交互状态(:hover、:focus、:active、:checked)必须成对设计。只做 hover 却没 focus 样式,键盘用户就卡在第一个菜单项上出不去;只做 active 却没 visited 基础样式,Safari 下整个悬停反馈就消失。可访问性不是加几个 ARIA 属性就完事,是整条交互链路都得稳。



















