CSS过渡自动高度不起作用
CSS过渡自动高度不起作用
我有一个网站,决定用纯CSS代码片段替换基于jquery的切换框。当我对过渡效果使用固定的高度值(CSS的最后几行)时,效果很好,但是当使用auto
值时,动画效果消失了,只有高度变化起作用!有没有办法在使用auto
值的情况下实现这个效果?我希望能够使用可变的文本而不用脚本。
CSS代码如下:
.ac-container{
宽度:400px;
外边距:10px auto 30px auto;
文本对齐:左对齐;
}
.ac-container label{
字体系列:'BebasNeueRegular','Arial Narrow',Arial,sans-serif;
内边距:5px 20px;
定位:相对定位;
z-index:20;
显示:块级元素;
高度:30px;
光标:指针;
颜色:#777;
文字阴影:1px 1px 1px rgba(255,255,255,0.8);
行高:33px;
字体大小:19px;
背景:#ffffff;
背景:-moz-linear-gradient(top, #ffffff 1%, #eaeaea 100%);
背景:-webkit-gradient(linear, left top, left bottom, color-stop(1%,#ffffff), color-stop(100%,#eaeaea));
背景:-webkit-linear-gradient(top, #ffffff 1%,#eaeaea 100%);
背景:-o-linear-gradient(top, #ffffff 1%,#eaeaea 100%);
背景:-ms-linear-gradient(top, #ffffff 1%,#eaeaea 100%);
背景:linear-gradient(top, #ffffff 1%,#eaeaea 100%);
过滤器:progid:DXImageTransform.Microsoft.gradient( startColorstr='#ffffff', endColorstr='#eaeaea',GradientType=0 );
盒子阴影:
0px 0px 0px 1px rgba(155,155,155,0.3),
1px 0px 0px 0px rgba(255,255,255,0.9) inset,
0px 2px 2px rgba(0,0,0,0.1);
}
.ac-container label:hover{
背景:#fff;
}
.ac-container input:checked + label,
.ac-container input:checked + label:hover{
背景:#c6e1ec;
颜色:#3d7489;
文字阴影:0px 1px 1px rgba(255,255,255, 0.6);
盒子阴影:
0px 0px 0px 1px rgba(155,155,155,0.3),
0px 2px 2px rgba(0,0,0,0.1);
}
.ac-container input{
显示:none;
}
.ac-container section{
背景:rgba(255, 255, 255, 0.5);
margin-top:-1px;
溢出:隐藏;
高度:0px;
定位:相对定位;
z-index:10;
-webkit过渡:高度 0.3s ease-in-out, 盒子阴影 0.6s linear;
-moz过渡:高度 0.3s ease-in-out, 盒子阴影 0.6s linear;
-o过渡:高度 0.3s ease-in-out, 盒子阴影 0.6s linear;
-ms过渡:高度 0.3s ease-in-out, 盒子阴影 0.6s linear;
过渡:高度 0.3s ease-in-out, 盒子阴影 0.6s linear;
}
.ac-container section p{
字体样式:斜体;
颜色:#777;
行高:23px;
字体大小:14px;
内边距:20px;
文字阴影:1px 1px 1px rgba(255,255,255,0.8);
}
.ac-container input:checked ~ section{
-webkit过渡:高度 0.5s ease-in-out, 盒子阴影 0.1s linear;
-moz过渡:高度 0.5s ease-in-out, 盒子阴影 0.1s linear;
-o过渡:高度 0.5s ease-in-out, 盒子阴影 0.1s linear;
-ms过渡:高度 0.5s ease-in-out, 盒子阴影 0.1s linear;
过渡:高度 0.5s ease-in-out, 盒子阴影 0.1s linear;
盒子阴影:0px 0px 0px 1px rgba(155,155,155,0.3);
}
.ac-container input:checked ~ section.ac-small{
高度:120px; /*auto*/
}
一些内容... 一些内容...
CSS 过渡自动高度不起作用的原因是无法对 "auto" 进行动画处理。通常的解决方法是对一个外层DIV的高度进行动画处理,该外层DIV只有一个无样式的DIV作为子元素,用于测量内容的高度。
具体的解决方法如下:
function growDiv() { var growDiv = document.getElementById('grow'); if (growDiv.clientHeight) { growDiv.style.height = 0; } else { var wrapper = document.querySelector('.measuringWrapper'); growDiv.style.height = wrapper.clientHeight + "px"; } }
#grow { -moz-transition: height .5s; -ms-transition: height .5s; -o-transition: height .5s; -webkit-transition: height .5s; transition: height .5s; height: 0; overflow: hidden; outline: 1px solid red; }
The contents of my div.The contents of my div.The contents of my div.The contents of my div.The contents of my div.The contents of my div.
这种方法比接受的答案更好。实际上,可能不需要 measuringWrapper
类。我使用类似下面的代码来检测要设置的高度:Array.from(growDiv.children).map(el => el.clientHeight).reduce((a, b) => a + b, 0)
这种方法可以实现高度的动画。谢谢。
CSS过渡自动高度不起作用的问题可能出现的原因是,当对象的scaleY为0时,DOM仍然保留了完整的高度。解决方法可以使用scaleY或clip来解决。使用scaleY时,可以将ul的transform属性设置为scaleY(0),并在p元素的:hover状态下将transform属性设置为scaleY(1)。使用clip时,可以将ul的clip属性设置为rect(auto, auto, 0, auto),并在h3元素的:hover状态下将clip属性设置为rect(auto, auto, 10rem, auto)。
以下是解决方法的代码示例:
使用scaleY:
ul { background-color: #eee; transform: scaleY(0); transform-origin: top; transition: transform 0.3s ease-in-out; } p:hover ~ ul { transform: scaleY(1); }
Here (scaleY(1))
- Coffee
- Tea
- Milk
使用clip:
ul { clip: rect(auto, auto, 0, auto); position: absolute; margin: 0; padding: .5rem; color: white; background-color: rgba(0, 0, 0, 0.8); transition-delay: 0.29s; transition-property: clip; transition-duration: 0.5s; transition-timing-function: cubic-bezier(0.175, 0.885, 0.32, 1.275); } h3:hover ~ ul, h3:active ~ ul { clip: rect(auto, auto, 10rem, auto); }
Hover here
- This list
- is clipped.
- A clip transition
- will show it
Some text...
此外,还有一种解决方法是使用max-height结合scale或translateY,以避免使用max-height在过渡顺序上出现的问题。这种方法可以在这里查看示例。
需要注意的是,clip属性已被废弃,但不会被淘汰。在CSS遮罩模块中,clip被弃用,推荐使用clip-path属性,但已经存在的clip属性不会消失。
在性能方面,使用scale而不是max-height是更好的选择。可以在Google开发者文档中的性能手册中了解到,使用will-change CSS设置可以提高性能。
CSS过渡自动高度不起作用的原因是,使用的是max-height
而不是height
进行过渡,并将max-height
设置为比实际高度大的值。解决方法是将过渡属性从height
改为max-height
,并调整过渡的速度。
为了解决这个问题,可以使用以下CSS代码:
.ac-container section{ ... max-height: 0px; ... transition: max-height 0.3s ease-in-out, box-shadow 0.6s linear; } .ac-container input:checked ~ section{ ... transition: max-height 0.5s ease-in-out, box-shadow 0.1s linear; ... } .ac-container input:checked ~ section.ac-small{ max-height: 500px; /*auto*/ }
此外,还可以使用JavaScript来获取实际高度并将其设置为max-height
的值。
此解决方法适用于从零到自动高度的过渡,而不是从自动高度到自动高度的过渡(即内容发生变化时)。
另外,有人认为使用flexbox布局会更好。