最稳妥的导航语义化写法是用 <nav> 包裹 <ul>,每个导航项必须为 <li>,横向布局推荐 display: flex,移动端折叠需结合 checkbox 或 JS,无障碍需 aria-current="page" 和焦点管理。

用 <nav> 包裹 <ul> 是最稳妥的语义化写法
浏览器和读屏工具能识别 <nav>,比纯 <div> 更可靠。别用 <div class="nav"> 模拟,除非有特殊兼容要求(比如要支持 IE8 以下)。
常见错误是把链接直接塞进 <nav> 而不套列表:这样既难样式控制,也不符合导航项“并列集合”的语义。
<nav><ul><li><a href="/">首页</a></li><li><a href="/about">关于</a></li></ul></nav>- 每个导航项必须是
<li>,不能用<span>或<div>替代 - 如果只有单个链接(比如仅“登录”按钮),
<nav>反而不合适,改用<header>或普通<div>
横向排列靠 display: flex,不是 float 或 inline-block
Flex 布局对齐简单、换行可控、响应式友好。老式 float 容易塌陷,inline-block 有看不见的空白符间隙,调试起来反而更费时间。
关键 CSS 就这几句:
立即学习“前端免费学习笔记(深入)”;
nav ul { display: flex; list-style: none; padding: 0; margin: 0; }
nav li { margin-right: 1rem; }
nav a { text-decoration: none; color: #333; }
-
margin-right放在<li>上比放在<a>上更稳定,避免点击热区错位 - 最后一项右侧多余间距?用
:last-child { margin-right: 0; }清掉 - 需要右对齐部分链接(比如用户头像)?给对应
<li>加margin-left: auto;
移动端折叠菜单得靠 @media + checkbox 或 JS,纯 CSS 无法监听点击
别信“只用 hover 就能做下拉”的方案——手机没 hover,且 iOS Safari 对 :focus-within 支持不稳定。
最小可用方案是用隐藏 <input type="checkbox"> 控制显示:
<input type="checkbox" id="menu-toggle"> <label for="menu-toggle">☰</label> <nav><ul>...</ul></nav>
然后用 #menu-toggle:checked ~ nav ul { display: flex; } 控制展开。注意:~ 是通用兄弟选择器,确保 HTML 结构里 <nav> 确实在 <input> 后面。
- label 必须带
for属性,且值与 input 的id严格一致 - 别用
<button>直接 toggle,否则屏幕阅读器可能不识别状态变化 - 如果项目已用 jQuery 或 Vue,优先用 JS 控制 class 切换,语义和可维护性更好
无障碍访问不能只靠 aria-label
加 aria-label="主导航" 到 <nav> 是基础,但更关键的是确保所有链接有明确、上下文独立的文本。比如“更多”“点击查看”这种词,对屏幕阅读器用户等于没说。
- 图标链接(如 ? 搜索)必须配
<span class="visually-hidden">搜索</span>,不能只靠 title 属性 - 当前页面对应的导航项,加上
aria-current="page",例如<a href="/about" aria-current="page">关于</a> - 键盘 Tab 流必须自然:从 logo → 首页 → 关于 → 联系 → 登录,不能跳到 footer 再绕回来
.focus() 手动控制。



















