最稳方案是用包菜单、设display: flex横向排列、主内容区加margin-top避让;因提供语义化导航识别,Flexbox避免传统布局缺陷,固定导航需预留空间且高亮须JS动态判断。

直接说结论:用 <nav></nav> 包住菜单,<ul></ul> 用 display: flex 横向排列,主内容区加 margin-top 避开固定导航栏——这是当前最稳、语义正确、响应式友好的组合。
为什么必须用 <nav></nav> 而不是 <div class="nav">
<p>这不是“看起来一样就行”的事。浏览器和读屏软件靠 <code><nav></nav> 标签识别“这里是导航”,否则键盘用户按 Tab 键会直接跳过整个区域;SEO 也会弱化该区块的权重。更实际的问题是:如果你后期加暗色模式或无障碍支持(比如 prefers-reduced-motion),没有语义标签,CSS 或 JS 就得绕一大圈做 hack。
- 一个页面可有多个
<nav></nav>,但别嵌套,也别把搜索框、登录按钮塞进去(它们该用 <search></search> 或 <form></form>)
- 面包屑导航如果也用
<nav></nav>,务必加 aria-label="当前位置",否则读屏器只报“导航”,不报上下文
display: flex 是横向排列唯一推荐方案
<nav></nav>,但别嵌套,也别把搜索框、登录按钮塞进去(它们该用 <search></search> 或 <form></form>)<nav></nav>,务必加 aria-label="当前位置",否则读屏器只报“导航”,不报上下文display: flex 是横向排列唯一推荐方案老式 float: left 或 display: inline-block 在现代项目里等于埋雷:父容器高度塌陷、换行时文字间隙错位、移动端字体缩放后错行……Flexbox 几乎没这些问题。
- 对
<ul></ul>设display: flex,子项<li>自动横排,不用清浮动 - 用
gap: 1rem控制间距,比给每个<li>加margin-right干净得多,也不用纠结“最后一个要不要清除 margin” - 主菜单文字长度不均时,
justify-content: space-around比space-between更均衡,两端留白一致 - 别在
<nav></nav>上写white-space: nowrap——小屏会强制横向滚动,改用flex-wrap: wrap+ 媒体查询自然折行
固定定位导航栏下,主内容区怎么不被遮挡
很多人只加 position: fixed 却忘了内容区要“让位”,结果首段文字永远被盖住。关键不是“撑开”,而是“预留空间”。
立即学习“前端免费学习笔记(深入)”;
- 导航栏高度设为
height: 56px(常见 Material Design 规范)或64px(iOS 大标题适配),主内容区就用对应margin-top: 56px或padding-top: 64px - 别用
top: 0+z-index: 999就完事——如果页面有 modal 或 toast,z-index冲突会直接导致导航栏被盖住;建议统一用 CSS 变量管理层级::root { --z-nav: 100; } - 如果导航栏高度是响应式的(比如小屏缩到 48px),
margin-top也要用媒体查询同步调整,不能写死
当前页高亮必须靠 JS 动态判断,不能硬编码 class="active"
HTML 本身不知道自己在哪一页。所有页面都手动写 class="active" 到某个 <a></a> 上,路径一变(比如从 /about 改成 /about/ 或加了哈希路由 #!/projects),高亮就失效。
- 简单前端判断逻辑(放



















