这个问题源自于掘金上的一个留言,一个朋友问到,为什么我下面这段代码的高度过渡动画失效了? 伪代码大概是这样: ```CSS { height: unset; transition: all 0.3s linear; will-change: height; &.up { height: 0; } &.down { height: unset; } } ``` 把它还原成一个实际的 Demo,效果大概是这样(本质想的想法是通过给元素切换它的 `.up`,`.down` 类,让它实现展开、合上的动画 ):  嗯哼?很奇怪,明明给 `height` 属性设置了 `transition`,为什么过渡动画没有触发,而是直接一步到位展开了呢? 我们期待的效果是这样的:  ## transition 不支持 height: auto 当上述代码设置成 `height: unset` 时,实际等同于设置了 `height: auto`,我们的想法是希望这段代码能够容器支持文本的动态高度。每次展开的时候,过渡展开到容器本身的高度即可。 查看规范,究其原因,在于 **CSS transtion 不支持元素的高度为 auto 的变化**。 如果把上述的 `height: unset` 替换成一个具体的高度值,则动画是生效的,譬如: ```CSS { &.up { height: 0; } &.down { - height: unset; + height: 500px; } } ```  但是,我们又希望能够做到动态高度的过渡转换,是不是就没有办法了么? ## 巧用 `max-height` 适配动态高度 嘿嘿,这里有一个非常有意思的小技巧。既然不支持 `height: auto`,那我们就另辟蹊径,利用 `max-height` 的特性来做到动态高度的伸缩。 我们改造一下上述代码,将 `height: 0` 替换为 `max-height: 0`,将 `height: auto` 替换成 `max-height: 1000px`,伪代码大概是这个意思: ```CSS { max-height: 0; transition: max-height 0.3s linear; &.up { max-height: 0; } &.down { max-height: 1000px; } } ``` 我们估算一下实际容器的最大高度,这里的 `1000px` 只需要比最大高度高即可。**但是这里不能设置的太高,最高是贴近最大的使用高度即可**,后面会聊到为什么。 由于 `max-height` 只是限制文本的最大高度,当容器的实际高度没有达到限制的最大高度,将不会继续变高,看看效果:  [CodePen Demo -- the height property transition unwork](https://codepen.io/Chokcoco/pen/YzGOjqQ) ### 小缺陷 整体效果还是非常的 Nice 的,当然,可能有两个小缺陷, 1. 如果实际场景中 `max-height` 需要用到并且有其它作用,那么可能这种方法就无法满足需求了 2. 另一个缺点就是视觉上有延迟,和实际高度相差越大越明显。也就是说,如果容器实际高度只有 200px,`max-height` 为 1000px,动画时间为 1s,缓动函数为 linear。实际动画从 0 到 200px 的高度过渡时间只有 0.2s,这一点需要非常注意~ 因为本来展开动画是期望将容器的高度用 1s 的时间拉伸至 1000px,实际在 200px 的时候就停止了,所以动画时间只有 0.2 秒。综上,方法是好方法,但是具体使用的时候要需要具体分析。 ## 最后 好了,一个小细节,希望对你有所帮助,本文到此结束,希望对你有帮助 :),想 Get 到最有意思的 CSS 资讯,千万不要错过我的 iCSS 公众号 😄 <img width=160 src="https://github.com/proxy/user-images.githubusercontent.com/8554143/54919342-6d0dfd00-4ef8-11e9-9ee8-fbae9241d89e.png"> 更多精彩 CSS 技术文章汇总在我的 [Github -- iCSS](https://github.com/chokcoco/iCSS) ,持续更新,欢迎点个 star 订阅收藏。 如果还有什么疑问或者建议,可以多多交流,原创文章,文笔有限,才疏学浅,文中若有不正之处,万望告知。
Activity
[-]CSS 技巧一则:height 过渡动画[/-][+]CSS 技巧一则:动态高度过渡动画[/+]Tonysmark commentedon Jan 12, 2021
🤞 (๑•̀ㅂ•́)و✧
YowaiCoder commentedon Jan 13, 2021
max-height 还一个缺点就是视觉上有延迟,和实际高度相差越大越明显……
chokcoco commentedon Jan 13, 2021
@fightingcat 试了下 还真是 感觉是个很影响实际使用的点
[-]CSS 技巧一则:动态高度过渡动画[/-][+]CSS 奇技淫巧:动态高度过渡动画[/+]smiler-rf commentedon Jan 20, 2021
使用max-height,为什么收缩过程的时间与设置的动画时间相等呢,而不是小于,动画不是作用在max-height上了吗,虽然容器实际展开高度只有200px
adouni1996 commentedon May 20, 2021
利用max-height实现展开和收缩动画有一个无法规避的缺陷:
多个高度不确定的块一起渲染,都需要用到这个展开和收缩的动画,那么max-height最合理的值是多少?
倘若有一个块的高度是50px,另一个块的高度是1000px
对于1000px的块来说,max-height的值为1000px是最合理的
但对于50px的块,max-height设置为1000px,会对用户体验造成极大的影响
所以利用单一的max-height值进行展开和收缩控制,并不适用于有多个高度不确定块的场景
多个高度不确定块,要实现展开收缩动画的功能,合理的解决方案应该是:
用js动态获取每个块的实际高度
利用js控制块展开和收缩前后的height
配合transition属性进行动画控制
forgiveForever commentedon Jul 5, 2024
还是得 获取一次元素 height 纯css 对于动态高度 做不到很优雅

element 的折叠 面板也是