必须用四层结构,因其符合语义化标准:为SEO和读屏器提供导航锚点,表无序集合,维持列表语义链,确保可聚焦、可点击且满足44×44px触控标准,缺一不可。

直接用 <nav><ul><li><a></a></li></ul></nav> 四层结构就能跑起来,不加 JS、不套框架、不写多余 class,5 分钟可上线。关键不是“怎么炫”,而是“怎么不崩”。
为什么必须用 <nav><ul><li><a></a></li></ul></nav> 而不是 <div> 堆砌
<p>浏览器和读屏器只认 <code><a></a> 是可交互元素;<div> 包文字再加 click 事件,键盘 Tab 焦点进不去,移动端点击热区只有文字宽高,44×44px 最低触控标准直接不达标。
<ul>
<li>
<code><nav></nav> 是语义锚点:SEO 加权、屏幕阅读器按 Ctrl+Alt+Insert+N 可跳转,不是视觉装饰
<ul></ul> 表达“无序集合”,分类导航天然无顺序,用 <ol></ol> 会误导辅助技术<li> 是列表项容器,不能省——否则 <ul></ul> 的语义链断裂,CSS 选择器 ul > li 失效<a></a> 必须带 href(哪怕暂填 #),否则 :hover 和 :focus 在 Safari 中部分样式被屏蔽
display: flex 替代 float 或 inline-block 的实操要点
老式布局在小屏下极易换行错位、父容器塌陷、间隙不可控;display: flex 是当前最稳的起点,IE11 也支持。
- 给
<ul></ul>设display: flex,不是给<nav></nav>—— 后者保留语义容器职责 - 用
gap: 1rem控制项间距,比margin-right干净;IE11 不支持gap时退回到margin-inline-end: 1rem并清最后一项 - 避免
white-space: nowrap—— 小屏会强制横向滚动;改用flex-wrap: wrap+@media (max-width: 768px)自然折行 -
<a></a>必须设display: block,否则点击热区仅限文字,悬停效果也只响应文字区域
移动端收起菜单不用 JS 的 CSS-only 方案
纯 CSS 实现汉堡菜单,加载失败也不瘫痪,适合静态站点或 CDN 托管场景。
立即学习“前端免费学习笔记(深入)”;
- HTML 中放一个隐藏
<input type="checkbox" id="menu-toggle">和对应<label for="menu-toggle">☰</label> -
<nav></nav>内部<ul></ul>默认display: none,用#menu-toggle:checked ~ nav ul触发显示 - 必须加
position: absolute或top: 100%,否则下拉时页面重排跳动 -
<meta name="viewport" content="width=device-width, initial-scale=1">必加,否则媒体查询失效
Safari 中 a:hover 失效的真正原因和修复
不是 CSS 写错了,是 Safari 对未访问链接(:link)和已访问链接(:visited)有硬性限制:hover 时不能改 background-color、border、transform 等属性,除非你显式声明基础样式。
- 统一加
a:link, a:visited { color: #333; text-decoration: none; } - 再写
a:hover { background-color: #f0f0f0; }才生效 - 不处理的话,iOS 用户会觉得“点不动”“没反馈”,尤其在微信内嵌浏览器中更明显
- 别依赖
!important强刷,Safari 会静默忽略
最容易被忽略的是:每个 <a></a> 的 href 必须真实可达,上线前不能留 #;否则用户点进去是空白页,而你还在查 CSS 是否写了 display: block。



















