必须用包裹主导航链接并配结构和aria-label,禁用;当前页需设aria-current="page",下拉菜单须支持键盘操作与aria属性。

用 <nav></nav> 包裹导航结构,别直接用 <div>
<p>语义化是第一步,<code><nav></nav> 告诉浏览器和读屏软件“这是主要导航区域”,对 SEO 和可访问性都有实际影响。很多新手直接套 <div class="menu">,结果在屏幕阅读器里被读成“普通容器”,用户得手动摸索。
<p>常见错误现象:<code>Navigation landmark not found(Lighthouse 或 axe 插件报的可访问性警告)
- 必须把主导航项(如首页、关于、联系)放在
<nav></nav> 内,页脚链接或面包屑一般不用
- 一个页面通常只用一个
<nav></nav>;多个时建议加 aria-label 区分,比如 <nav aria-label="主导航"></nav>
- 不要嵌套
<nav></nav> —— 比如下拉菜单里再写一层 <nav></nav>,反而干扰语义
链接用 @#@#@#@#@#@#@#@#@#@0。
<nav></nav> 内,页脚链接或面包屑一般不用<nav></nav>;多个时建议加 aria-label 区分,比如 <nav aria-label="主导航"></nav>
<nav></nav> —— 比如下拉菜单里再写一层 <nav></nav>,反而干扰语义@#@#@#@#@#@#@#@#@#@0。
当前激活页的处理很关键:纯靠 CSS 类(如 class="active")无法被读屏器识别,必须加 aria-current="page"。
-
@#@#@#@#@#@#@#@#@#@1—— 读屏器会读作“关于,当前页面” - 不要写
aria-current="true"或aria-current="active",只有"page"、"step"、"location"是合法值 - 服务端渲染时由后端判断并注入该属性;前端路由(如 React Router)需用
useLocation+aria-current手动同步
水平排列用 display: flex,别依赖 float 或 inline-block
float 已淘汰,inline-block 有看不见的空白符问题(换行/缩进会变间距),Flex 是目前最稳的方案。
nav ul {
display: flex;
list-style: none;
margin: 0;
padding: 0;
}
nav li { margin-right: 1rem; }
nav a { text-decoration: none; color: #333; }
- 必须重置
ul的默认margin和padding,否则左右留白不一致 - 移动端要加
@media折叠为汉堡菜单,但基础 HTML 结构不变 —— 别为了“响应式”把<ul><li></ul>换成<div> 堆砌 <li>如果用 CSS Grid 替代 Flex,注意 <code>grid-auto-flow: column才能横排,且兼容性略低(IE 不支持) - 父级
<li>加role="menuitem",子菜单<ul></ul>加role="menu"和hidden属性 - 用
Enter/Space展开,Esc收起,ArrowDown进入子项 —— 这些不能只靠 CSS - JavaScript 必须监听
focusin事件来动态控制hidden,而不是只靠:focus-within(Safari 旧版不支持)
下拉菜单必须支持键盘操作,hover 不够用
仅靠 :hover 实现下拉,在触屏设备和键盘用户(Tab 键导航)面前完全失效。真实可用的下拉需要 focus、keydown 和 ARIA 属性配合。











