max-height 动画必须设具体数值,因浏览器无法对 auto 插值;推荐 transform: scaley() 或 details/summary 原生方案,兼顾性能与无障碍。

直接用 max-height 做过渡最省事,但必须设具体数值(不能是 auto),否则动画跳变或失效;真要丝滑且高度不可预知,得靠 JS 测 scrollHeight + 强制重排,再配 overflow: hidden。
为什么 max-height: 0 → max-height: auto 不会动动画
浏览器无法对 auto 插值——它不知道“自动”等于多少像素,transition 直接被忽略,变成瞬间显隐。你写的 CSS 没错,是 CSS 引擎能力边界问题。
-
max-height必须是确定值,比如max-height: 400px,且要略大于内容最大可能高度(含 padding、line-height 等) - 若内容含图片或富文本,加载后高度变化,固定值容易截断或留白,此时不推荐纯 CSS 方案
- 过渡属性必须写在“有高度变化”的元素上,不是 header,也不是 wrapper,而是那个实际展开/收起的
.accordion-panel元素
用 transform: scaleY() 替代高度过渡更稳妥
GPU 加速、不依赖内容测量、无卡顿风险,适合移动端或动态内容。但要注意它不影响文档流,下方元素不会自动推移——这点和 display: block/none 或 max-height 行为不同。
- 收起时设
transform: scaleY(0)+overflow: hidden,展开时设transform: scaleY(1) - 必须加
will-change: transform,尤其在 Safari 上,否则动画掉帧 - 不要给目标元素设
height: auto或padding-top/bottom,它们不参与scaleY变形,会导致视觉错位 - 如需下方内容跟随推移,得额外包一层
div控制height,或改用display切换
用 details/summary 是最简无障碍方案
原生语义化、自带键盘支持(空格/回车)、屏幕阅读器友好、无需 JS。但动画受限,IE 完全不支持,样式定制也较弱。
- 动画只能靠
details[open] > *:not(summary)配合opacity+transform淡入+下滑,不能直接过渡height - 若强制用
max-height,仍得设死值(如max-height: 500px),否则展开时抽搐 - JS 干预时,重点同步
aria-expanded和aria-hidden,而不是重写展开逻辑 - 别试图用 CSS 选中 “未展开时的
details内容”,它此时是display: none,伪类无效
响应式关键不在动画,而在结构与触发区域
折叠面板是否“响应式”,主要看小屏下点击区域是否足够大、文字是否可读、间距是否合理,动画只是锦上添花。
- 标题按钮的点击热区至少 44×44px(符合 WCAG),别只让文字可点,整行加
padding或min-height - 移动端慎用 hover 效果,优先用 active 状态或 focus-visible
- 单开模式(一次只展开一个)纯 CSS 实现不了,
:checked和details都是各自独立,必须靠 JS 管理状态数组 - BEM 类名如
accordion__header--is-open应绑定在 header 上,不是 content 区——这是交互源,不是状态容器
真正难的不是写过渡,而是判断什么时候该用 details、什么时候必须 JS 测高、什么时候干脆放弃高度动画改用 fade+slide。多数项目里,max-height 设个安全上限 + padding 过渡,已经覆盖 80% 场景;剩下那 20%,往往卡在 JS 同步时机或可访问性补全上。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











