max-height过渡不生效是因为0→auto无法计算像素值,需用固定值如16rem替代;纯css切换靠:checked+兄弟选择器;触摸设备需active类或details/summary;可访问性须加aria-expanded、role和prefers-reduced-motion支持。

vertical-menu用max-height过渡为什么总不生效
因为max-height从0过渡到auto时,浏览器无法计算auto对应的具体像素值,动画直接跳变。必须用一个“足够大但不过分夸张”的固定值替代auto。
- 常见错误:写
max-height: 0; → max-height: auto;,看起来写了transition但完全没动画 - 安全取值:估算菜单最多展开几项(比如8项 × 行高2rem ≈ 16rem),设为
max-height: 16rem; - 如果内容动态增减,宁可略大(如
50rem),也不要小——小了会截断,大了只是多占点过渡时间 - 记得同时控制
overflow: hidden;,否则超长内容会撑开容器破坏折叠效果
如何让点击切换菜单收/展状态(纯CSS方案)
纯CSS依赖:checked伪类 + 隐藏的<input type="checkbox">,配合兄弟选择器控制菜单高度。js不是必须,但得接受它的局限性。
- 结构上,
<input id="menu-toggle">必须放在<nav></nav>之前,且<nav></nav>要用~或+紧邻它(如#menu-toggle:checked ~ nav) - 触发按钮用
<label for="menu-toggle"></label>,别用<button></button>——后者无法联动:checked - 移动端要注意:ios safari对
:checked+max-height过渡偶尔有渲染延迟,加transform: translateZ(0);可缓解
垂直菜单折叠后,子菜单悬停展开怎么兼容触摸设备
悬停(:hover)在手机上基本失效,纯靠:hover做二级菜单会丢失交互。必须为触摸场景补一层点击逻辑。
- 别只写
.submenu:hover { max-height: 20rem; },要搭配.submenu.active { max-height: 20rem; } - 用
click事件给.submenu切active类,同时阻止冒泡避免父菜单收起 - 如果坚持纯CSS,可用
details/summary替代:它原生支持点击展开+语义化+无障碍,且summary可样式化成箭头按钮 - 注意
details在旧版edge(≤18)不支持,需确认目标用户环境
折叠菜单的可访问性容易被忽略的三个点
屏幕阅读器不会自动感知max-height变化,也不懂“点击展开”暗示,必须手动补全语义和状态反馈。
立即学习“前端免费学习笔记(深入)”;
- 折叠状态的按钮要带
aria-expanded="false",展开后改为"true" - 菜单容器加
role="region"和aria-labelledby指向控制按钮,让屏幕阅读器知道这是哪块区域 - 用
prefers-reduced-motion媒体查询关掉过渡动画:@media (prefers-reduced-motion: reduce) { * { animation-duration: 0.01ms !important; } },否则部分用户会头晕
事情说清了就结束。