关键不是flex-wrap折行,而是用媒体查询+display切换控制可见性层级;flex-wrap仅换行渲染,无法真正折叠、无动画、不响应交互;应按优先级逐层隐藏非核心项,汉堡图标需正确关联checkbox并用clip隐藏,max-height过渡替代height:auto。

大屏不折行、小屏自动收起,关键不是靠 flex-wrap 硬折,而是用媒体查询 + display 切换控制可见性层级。
为什么 flex-wrap 不适合做导航栏折叠
它只是让 li 换行堆叠,但所有链接仍会渲染在页面上——小屏下可能挤成一行文字、触发横向滚动,或把导航栏撑得过高。真正的“折叠”是让非核心项彻底不参与布局流。
- 折行 ≠ 折叠:用户不需要看到“首页 About Services Contact”垂直堆成四行,而是只看到一个汉堡图标
-
flex-wrap: wrap无法配合过渡动画,也无法响应点击交互 - 屏幕旋转时,
wrap不会自动切回单行,容易残留错位
@media (max-width: 768px) 下必须隐藏哪些元素
不是“隐藏菜单”,而是按优先级逐层收起:主导航项 > 搜索框 > 下拉触发按钮 > 副标题/徽标文字。否则小屏会出现空白占位或错位图标。
- 默认用
display: none隐藏整个.nav-menu容器(不是只 hideli) - 搜索框若独立于
.nav-menu外,必须一并加进媒体查询隐藏逻辑,否则它会孤零零悬在右上角 - 下拉菜单的触发按钮(如
.dropdown-toggle)要设display: none,同时其子菜单.dropdown-menu也需设display: none—— 否则小屏点开后还得再点一次才展开内容 - 避免用
visibility: hidden替代display: none:前者仍占空间,会导致父容器高度异常
折叠按钮(汉堡图标)的 DOM 位置和绑定方式
它必须是 label,且 for 属性指向一个同级前置的 input[type="checkbox"],否则 :checked ~ .nav-menu 选择器失效。
- 正确顺序:
<input id="nav-toggle" type="checkbox"><label for="nav-toggle">☰</label><nav class="nav-menu">...</nav> - 错误写法:
<label><input type="checkbox">☰</label>(隐式关联虽可用,但 iOS Safari 有时不触发 focus) - 更稳妥的隐藏 checkbox 方式:
position: absolute; clip: rect(0 0 0 0);,而不是opacity: 0或visibility: hidden—— 后两者会影响可访问性 - 不要给
label加onclick或preventDefault:它本职就是触发 checkbox,加 JS 反而破坏键盘导航和屏幕阅读器支持
过渡动画里最常被忽略的 max-height 陷阱
height: auto 无法做 CSS 过渡,所以不能直接从 height: 0 → height: auto。硬写会跳变,或者根本不动。
- 必须用
max-height:设一个足够大的值(如max-height: 500px),确保所有菜单项都能完整展开 - 配合
overflow: hidden,否则内容会溢出并显示滚动条 - 过渡要写全:
transition: max-height 0.3s ease-in-out, opacity 0.3s;只写一个属性,动画会不连贯 - 如果菜单项动态增减(比如 JS 插入新
li),500px可能不够——此时纯 CSS 方案已到边界,该换 JS 控制scrollHeight了
真正难的不是让菜单“动起来”,而是让状态在屏幕缩放、设备旋转、焦点切换之间保持一致。比如 iOS Safari 旋转后,:checked 状态还在,但 .nav-menu 却卡在 max-height: 0;又比如用户用键盘 Tab 到汉堡图标再空格,却没触发展开——这些细节不压测几轮真发现不了。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











