不能用 height: auto 做过渡,因为浏览器无法对其插值动画;必须用 max-height 替代,并设为足够大但不过大的固定值(如 60rem),配合 overflow-hidden 实现平滑过渡。

为什么不能用 height: auto 做过渡
浏览器无法对 height: auto 进行动画插值,结果就是内容“啪”一下弹出或消失,毫无平滑可言。这不是你 CSS 写错了,是规范限制——CSS 动画只能在确定数值间线性过渡。
常见错误现象:加了 transition: height 0.3s 却没效果;或者展开时有动画、收起时直接坍缩。
- 必须用
max-height替代height -
max-height值得是“足够大但不过大”的固定值,比如60rem(≈960px) - 设太小:长内容被裁切、文字显示不全
- 设太大:动画时间失真(0 → 1000px 耗时远超实际需要)
- 绝对避免
max-height: 100vh——软键盘弹出、横屏、缩放都会导致重排抖动
如何用 max-height + overflow 实现可靠过渡
核心结构是「默认折叠态」→「展开态」的 class 切换,配合 overflow-hidden 控制内容显隐。关键不是让高度“刚好”,而是让过渡“可信”。
- 折叠态:
max-h-0 overflow-hidden - 展开态:
max-h-[60rem] overflow-visible(Tailwind 中需用方括号语法生成该值) - 过渡声明写在基础类上:
transition-max-h duration-300 ease-in-out - 不要在 JS 里写
el.style.maxHeight = el.scrollHeight + 'px'——破坏原子类体系,且 SSR 下易失效 - 若需动态适配,可在 class 切换后用
getComputedStyle(el).maxHeight验证是否生效,而非读取scrollHeight
details + summary 是最省心的语义化方案
原生 details 元素自带状态管理、键盘支持(空格/回车)、屏幕阅读器兼容,CSS 只管样式,逻辑零成本。
-
summary必须是details的第一个子元素,且不能自闭合(<summary></summary>,不是<summary></summary>) - 动画别硬刚
height,改用opacity+transform: translateY()更稳妥(如@keyframes slideDown) - 想加旋转箭头?用
summary::after+details[open] summary::after { transform: rotate(90deg) } - Safari 15.4+ 才支持
::marker,旧版需用list-style: none+ 伪元素模拟 - 多个
details默认独立开关;要“单开单关”,必须监听toggle事件并手动 close 兄弟节点
用 checkbox + :checked 实现无 JS 多面板控制
适合需要完全静态渲染、SEO 友好、或 SSR 场景。每个面板互不干扰,结构清晰,样式自由度高。
- HTML 结构:隐藏
<input type="checkbox" id="section1">,用<label for="section1"></label>触发 - CSS 选择器关键:
.accordion-toggle:checked + .accordion-title + .accordion-content -
max-height值建议设为200px或40rem,比内容略高即可 - 移动端注意点击区域:确保
label足够大(至少 44×44px),避免误触 - 若内容高度差异极大,可结合 JS 在挂载后动态写入
style.maxHeight,但仅限首次计算,之后仍靠 class 切换
真正容易被忽略的是收起动作本身——很多人只写了展开的 max-h-[60rem],却忘了收起必须回到 max-h-0,且两者都得带 overflow-hidden,否则内容会闪现或留白。动画是否平滑,一半靠展开,另一半靠收起的收束精度。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











