height: auto 无法参与 css transition,因浏览器无法计算其数值;应改用 max-height 过渡或 js 测量 scrollheight 后设置具体 height 值实现平滑展开。

height: 0 → height: auto 为什么不能直接过渡
CSS 的 transition 对 height 做动画时,height: auto 是无效的起始或结束值——浏览器无法计算它的数值,过渡会立刻跳变。这不是你写错了,是 CSS 规范本身不支持 auto 参与过渡。
常见错误现象:height: 0; transition: height 0.3s; + height: auto; → 动画不触发,文字“啪”一下全出来。
- 必须用具体数值(如
height: 24px)或可计算单位(em、rem、vh)替代auto - 如果行高固定,可用
max-height替代height,它支持从0过渡到足够大的值(比如max-height: 500px) - 若内容高度不可预估,需 JS 测量真实
scrollHeight后设为height,再触发动画
用 max-height 实现逐行展开(最简可行方案)
这是纯 CSS 下最稳妥的做法,适用于行数相对可控、字体/行高固定的场景,比如 FAQ 折叠面板、简介段落收起。
关键点:用 max-height 模拟高度变化,配合 overflow: hidden 隐藏溢出,过渡时间控制节奏感。
立即学习“前端免费学习笔记(深入)”;
-
max-height的目标值必须大于内容实际高度(例如设成max-height: 20em),否则会截断 - 起始状态设
max-height: 0; opacity: 0; visibility: hidden;,结束状态恢复opacity: 1; visibility: visible;,避免点击瞬间闪现 - 过渡时间建议 0.3–0.45s,太快像抽搐,太慢显得卡顿;加
ease-out更自然
.line-reveal {
max-height: 0;
opacity: 0;
visibility: hidden;
overflow: hidden;
transition: max-height 0.35s ease-out, opacity 0.35s, visibility 0.35s;
}
.line-reveal.active {
max-height: 20em;
opacity: 1;
visibility: visible;
}
JS 配合 getComputedStyle / scrollHeight 精准控制高度
当内容动态生成、字体响应式变化、或需要严格按行数逐行显现(比如打字机+逐行淡入),CSS 的 max-height 就不够用了——得靠 JS 获取真实高度后设置 height。
容易踩的坑:offsetHeight 在元素未渲染时返回 0;getBoundingClientRect().height 受 transform 影响;最可靠的是 scrollHeight(含 padding,不含 border/margin)。
- 先设
height: 0+overflow: hidden,再强制重排(offsetHeight读取一次) - 立即读取
element.scrollHeight,赋给style.height - 用
requestAnimationFrame或setTimeout(..., 0)确保样式已应用再触发动画 - 动画结束后清理内联
height,还原为auto(否则影响后续响应式布局)
逐行显现 ≠ 打字机动画,别混淆两个需求
“逐行显现”本质是垂直方向上的展开控制,不是字符级的输入模拟。如果误用 @keyframes + ch 单位做“逐行”,会发现:换行符不被识别、中英文混排错位、white-space 处理异常。
真正需要逐行(而非逐字)动画时,优先考虑结构拆分:
- 把每行内容包在独立
<div> 或 <code><p></p>中,用:nth-child(n)控制延迟 - 用
display: inline-block+vertical-align: top避免inline元素受空格/换行影响 - 若必须单个元素内实现,用
line-clamp+transition控制显示行数(仅现代浏览器支持)
复杂点在于:行高随字体大小、line-height、font-feature-settings 动态变化,纯 CSS 很难自适应。这时候该接受 JS 测量的必要性,而不是硬套一个“看起来能动”的方案。










