:checked ~ .nav-menu不生效的根本原因是dom顺序错误,要求input与.nav-menu同级且input在前,label的for必须严格匹配input的id。

为什么:checked ~ .nav-menu不生效
这是纯 CSS 响应式导航最常卡住的点。根本原因不是写法错,而是 DOM 顺序不对。:checked ~ .nav-menu 依赖通用兄弟选择器 ~,要求 <input type="checkbox"> 和 .nav-menu 必须同级、且 input 在前。
-
<input id="nav-toggle" type="checkbox">必须直接放在<nav class="nav-menu"></nav>的同一父容器内,不能套在<div> 里,也不能插进 <code><nav></nav>内部 -
label的for属性值必须和input的id完全一致(大小写、连字符、拼写) - 如果结构是
<nav><input></nav>,那~就查不到目标——它只找“后面”的兄弟,不找子元素 - 初始状态设
max-height: 0+overflow: hidden,不是display: none - 展开时给足够余量:
input:checked ~ .nav-menu { max-height: 300px; }—— 这个值得略大于所有菜单项总高度,设小了动画会中途戛然而止 - 桌面端必须重置:
@media (min-width: 769px) { .nav-menu { max-height: unset; overflow: visible; } },否则大屏下还受小屏逻辑影响 - 别用
<button type="submit"></button>或<a href="https://www.php.cn/link/93ac0c50dd620dc7b88e5fe05c70e15b"></a>替代<label></label>,前者会触发跳转或提交,菜单闪一下就消失 -
label自身要撑出足够热区:加padding: 12px或设min-width: 44px; min-height: 44px - 漏了视口声明:
<meta name="viewport" content="width=device-width, initial-scale=1">—— 没这句,@media (max-width: 768px)在手机上基本失效 - 每个导航项(如
.nav-link)加min-width: 0,允许文本折行或缩放 - 若设了
white-space: nowrap,必须配套overflow: hidden+text-overflow: ellipsis(仅单行有效) - 别在同一个规则里混写
flex-direction: row和column,必须用媒体查询彻底分离:小屏切flex-direction: column,比wrap更稳定、更少意外
小屏下菜单展开动画卡顿或突然截断
用 display: none + display: flex 切换,动画根本不会动;用 visibility: hidden 又占布局空间,导致点击区域偏移。真正能过渡的只有 max-height + overflow: hidden。
汉堡按钮点了没反应,但 HTML 和 CSS 看着都对
问题往往不在 JS,而在默认行为或触控细节。iPhone SE 等小屏设备要求可点击区域 ≥ 44×44px,仅靠图标尺寸远远不够。
Flex 布局在小屏下换行错乱、文字被压缩
很多人以为 flex-wrap: wrap 能自动适配,结果小屏上文字挤成一团、高度突变甚至溢出容器。这不是 Flex 不行,是没关掉子项的“抗缩”机制。











