CSS3 Transition值为Auto的情况

实习了快一个月了,一个人在外还是有些忙的,上个月也没写博客了,最近跟着师兄做一个开源的项目Ant Design,在Github上开源了。虽说是跟着做,实际就是打打杂,写两个基本简单的组件。写之前也是简单学习了React这个现在来看火的发烫的前端库(or框架?),网上有文档也有教程,跟着把DEMO都写了一遍,虚拟DOM真神奇,就像去年这个时候认识AngularJS一样,给你颠覆的感觉,不过感觉的程度不及AngularJS。

好像说了不少和CSS3无关的东西,来了。

实现一个Notification组件,大概就是通过事件触发来生成一个消息提醒框,在窗口的右上角,加个动画效果,进场动画是框框从右侧闪出来,这个简单,本来宽度是定的,lefttransition一下就好了,opacity也给动一下就搞定了。

出场动画来了,高度和透明度都变为0就好,效果不错,看看怎么实现:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
&-fade-leave {
opacity: 1;
margin-top: @noticeMarginTop;
padding-top: @noticePadding;
padding-bottom: @noticePadding;
height: auto;
transition: all .3s ease-in-out;
}

&-fade-leave&-fade-leave-active {
opacity: 0;
height: 0;
margin-top: 0;
padding-top: 0;
padding-bottom: 0;
}

因为每个框框的内容都不一样多,高度绝对不能写死,那就不设置吧,让它自己撑开就好。调试动画的时候发现根本不是你想要的样子。从auto直接变到0,简直就是闪现的逆过程,难道这么简单的CSS3都没有实现吗?

答案是确实没有实现,估计比我们想象的要难许多,既然auto到0实现不了,那就算了吧!什么?强迫症怎么能算了!

某度某哥某Stackoverflow通通查一遍,好像也有同胞遇到过这样的问题,好像用的max-,值设为一个所有可能值的最大值,再加上overflow:hidden来解决这个问题:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
&-fade-leave {
opacity: 1;
margin-top: @noticeMarginTop;
padding-top: @noticePadding;
padding-bottom: @noticePadding;
max-height: 150px;
transition: all .3s ease-in-out;
}

&-fade-leave&-fade-leave-active {
opacity: 0;
max-height: 0;
margin-top: 0;
padding-top: 0;
padding-bottom: 0;
}

刚开始我没懂这个是什么原因,后来相同了就觉得非常简单,max-height设为一个较大的值,这个值从auto``transition为0的时候,由于overflow:hidden的作用,看上去就像是heightauto变为0。

看似完美的解决了这个问题,注意前文说的,max-height设为一个较大的值,这个值一般为所有可能值中最大的一个,为什么呢?

简单分析一下,若不是最大值,动画一开始的时候就把这个height变为这个非最大值,这个过程(其实时间极短,就像是很突兀的改了height一样的闪动),如果这个框框的高度和这个非最大值差距大的话,恭喜你,这个动画是失败的,会有明显的卡顿;

再看看为最大值的情况,这个很好理解,不会出现动画一开始的卡顿,可是,又有情况来了,若该框框高度比较小,细心的你会发现动画怎么延迟触发了?因为延迟的这段时间消耗在max-height到实际的height中。

这么来说,这个问题现阶段还没有很好的解决办法,除非用JS写动画,JS写动画本来就比较恶心了,又是React的虚拟DOM里的动画,官方建议使用CSS3来实现动画,因为虚拟DOM写动画简直操蛋,其次,浏览器要是实现了transition值为auto这个功能那才算完美的解决了这个问题。

无论值设为最大值还是非最大值,都会有或大或小的瑕疵,而又没有完美的解决方案,折中吧,尽量让可能值的范围稳定,如果设为最大值卡顿很明显的话,试试设置成较大值,至于这么值具体多少,去多试试,直至动画效果满意为止,那要是没有满意的怎么办?

  • 放弃这个动画
  • JS实现这个动画
  • 让浏览器去支持这个功能:)

同理,auto到0是这样,那么0到auto和这个是差不多的,互逆关系。

DEMO戳这里 在Github上有代码

Fork me on GitHub