当前位置: 首页 > 科技观察

CSS如何让autoheight完美支持转场动画?

时间:2023-03-13 17:34:17 科技观察

众所周知,当设置高度为auto关键字时,transition过渡动画是不会被触发的。以下是伪代码。div{高度:0;transition:1s}.wrap:hoverdiv{height:auto}效果如下:如果你想在展开的时候有过渡动画,比如这样。kapture2023-01-31at19.21.02通常使用JS动态获取元素高度(有点麻烦,渲染后需要知道高度)。其实CSS也有解决方案,就是用max-height来适配动态高度。以下是伪代码。div{最大高度:0;transition:1s}.wrap:hoverdiv{max-height:800px/*近似值,需要超过元素的高度*/}有兴趣的可以参考这篇文章:CSStricksandtricks:Dynamicheighttransitionanimation[1],但是有一个限制,高度差越大,过渡效果越差,假设元素的真实高度只有100px,如果max-height是800px,那么只有前1/8会有动画,像这样。那么,有没有更好的方法来解决这个问题呢?当然有,这次介绍一种全新的实现高度动态过渡的方式,一起来看看1.网格布局中的fr单元网格布局中新增了一个fr单元,用于定义网格轨道尺寸的弹性系数。Grid布局比较复杂,不可能三言两语说清楚。有兴趣的可以参考相关的网格教程,比如张新旭老师自己写的display:gridlayouttutorial[2]。大魔老师的现代网页布局[3].这里简单介绍下fr单元的用途,比如有这样的布局。1fr1fr1fr

关键样式如下:.grid{display:grid;grid-template-columns:repeat(3,1fr);}可以得到这样的效果:这里的repeat(3,1fr)其实是1fr1fr1fr的缩写,意思是3平分剩下的空间。也可以设置在垂直方向。.grid{grid-template-rows:repeat(3,1fr);}效果如下:也可以改变各自的分配比例。.grid{grid-template-rows:1fr2fr1fr;}效果如下:现在看一个特例,也可以设置分配比例为0fr。.grid{grid-template-rows:0fr2fr1fr;}效果如下:是不是有点奇怪,为什么0fr和1fr的比例一样?其实这是由网格的最小尺寸规则决定的。此时最小高度为min-content,由内部文字决定。如果没有文字,0fr自然不会占用空间。下面是去掉文字后的效果。如果你想保留文字而不占用空间怎么办?最小尺寸可以直接手动设置。span{min-height:0}这样0fr就不会占用空间了。您还可以借助out-of-hiding完全隐藏子内容。.grid{overflow:hidden;}span{min-height:0}效果如下:应该比较容易理解,那跟动画有什么关系呢?然后往下看2.可能有同学会疑惑grid中的过渡动画,何必纠结这个0fr呢?下面就来一探究竟吧。如果重置1fr,子内容将重新出现。.grid{grid-template-rows:1fr2fr1fr;}重点来了,grid中的fr单元也支持过渡动画(0fr=>1fr)。.grid{网格模板行:1fr2fr1fr;transition:.3s}效果如下:因为高度是通过内部文本扩展的,即高度是不确定的,从0fr到1fr的过渡变化相当于实现了变高的Transition动画。进一步简化,可以达到这个效果。这是不固定高度动画的雏形,多一点文字也完美支持。Kapture2023-01-31at19.48.37完整的demo可以在以下任意链接查看CSS自动高度转换(juejin.cn)[4]CSS自动高度转换(codepen.io)[5]CSS自动高度转换(runjs.work)[6]三、自适应高度动画的两个例子下面根据以上原理实现两个例子。先看文章开头的例子,HTML结构是这样的。鼠标放上去试试

欢迎关注前端大神,这里有一些你可能不知道的有趣的HTML、CSS和JS技巧,比如这篇文章,如何使自动高度支持过渡动画?一起来看看

简单的修改,应该是比较容易的,就可以得到这样的效果:然后用上面的技巧隐藏下拉内容,按键样式如下:.网格{显示:网格;网格模板行:0fr;过渡:.3s;overflow:hidden;}.grid>div{min-height:0;}然后hover触发显示,即改变grid-template-rows。.wrap:hover.grid{grid-template-rows:1fr;}这样就实现了变高的过渡动画。完整的demo可以查看以下任一链接:CSS自动降高(juejin.cn)[7]CSS自动降高(codepen.io)[8]CSS自动降高(runjs.work)[9]如果只是一个悬浮窗,因为是绝对定位,不会影响其他布局。其实可以用transformscale来缩放。让我们看另一个更实际的例子。公共菜单展开和折叠,就像这样。可以看到在展开的同时,下面的元素也被压低了,这样的效果更加自然,是transform无法实现的。这里的切换是通过:checked实现的,关键代码如下:Workbench
  • 项目列表
  • 数据配置器
ul{min-height:0;}.sub{display:grid;网格模板行:0fr;过渡:0.3s;溢出:隐藏;}:检查?。sub{grid-template-rows:1fr;}完整的demo可以在以下任一链接查看:CSS自动高度菜单(juejin.cn)[10]CSS自动高度菜单(codepen.io)[11]CSSauto高度菜单(runjs.work)[12]四.注意事项和一些限制下面是一些注意事项。这里的动画来自grid-template-rows的变化,即0fr到1fr。注意,注意,注意,这里的0fr必须是0fr,不是0也不是0px,必须是fr单位。下面是改为40px的效果(动画丢失)。而且0fr不支持calc计算,所以直接认为是非法的。这意味着,例如,您希望默认具有固定高度(非零),然后扩展到自适应高度。这种方法不能实现转场动画,有点遗憾