最稳方案是<nav>包<ul>配display: flex布局,禁用float;因<nav>提供语义地标供读屏器识别,<ul><li>确保键盘导航与SEO,flex天然支持对齐、折行与响应式。

直接用 <nav> 包 <ul>,配 display: flex 布局,别碰 float —— 这是当前最稳、可访问性最好、也最容易维护的组合。
为什么必须用 <nav> + <ul> 而不是 <div> 堆链接
屏幕阅读器只认 <nav> 为“可跳转导航地标”,按 D 键就能直抵;<div class="menu"> 对它来说只是“一个区域”,毫无语义。内部若不用 <ul><li><a>,而是 <div><a> 并列,键盘 Tab 顺序会乱,某些旧读屏甚至跳过整个菜单。错误写法:<nav><div><a>首页</a><a>设置</a></div></nav> —— 违反 HTML 规范,<nav> 里不能直接放 <a>。
display: flex 布局怎么设才不翻车
老式 float: left 容易塌陷、换行错位、移动端难适配;flex 天然支持对齐、等分、自动折行,但有几个硬约束:
-
<nav>或其子容器(如<ul>)必须设display: flex,且flex-wrap: wrap可让小屏自然折行,比 JS 切换更轻量 - 若要右侧放用户头像或通知图标,用
justify-content: space-between,左边 logo/菜单,右边操作项,一行搞定 - 每个
<a>必须设display: block或inline-block,否则点击热区仅限文字,hover 效果也只在文字上生效 - 避免给
<a>设固定height却不配line-height,会导致垂直居中失效、文字偏上
固定定位时 body 为什么一定要加 padding-top
用 position: fixed 后,<nav> 脱离文档流,不占位,首屏内容会被盖住。常见错误是只加 top: 0 却忘了补空间:
立即学习“前端免费学习笔记(深入)”;
- 必须给
<body>或主内容容器加padding-top,值 ≥ 导航高度(比如60px) - 用
position: sticky可省这步——只要设top: 0,浏览器自动保留占位,但需注意兼容性(IE 不支持) - 如果导航里有下拉菜单,其父级
<li>必须设position: relative,否则position: absolute的子菜单会相对视口定位,飘到页面任意位置
移动端汉堡菜单的 DOM 结构和可访问性底线
纯 CSS 实现收起/展开最可靠,但结构和属性缺一不可:
- 隐藏开关用
<input type="checkbox" id="menu-toggle">,触发按钮用<label for="menu-toggle">☰</label>,避免 JS 加载失败导致菜单完全不可用 - 菜单
<ul>默认display: none,用#menu-toggle:checked ~ nav ul控制显隐(注意选择器层级) - 下拉层必须用
position: absolute或top: 100%,否则display: block会撑开布局,页面跳动 - 必须加
aria-expanded和aria-controls,且值与目标容器id匹配;焦点顺序要连贯:汉堡按钮 → 第一个菜单项 → 下一个可聚焦元素
真正容易被忽略的是:Safari 对 a:hover 有严格限制,未定义 a:link 和 a:visited 时,background-color 等属性 hover 无效——所有导航链接务必统一加 a:link, a:visited { color: #333; text-decoration: none; }。



















