不定高度的过渡动画
方法1
max-height,高度不一致,时间不自然
方法2
clip-path:inset,支持transition,缺点,会占据空间,需设置绝对定位来清除空间
.content { ... height: auto; clip-path: inset(0 0 100% 0); } .fold:hover .content { clip-path: inset(0); }
方法3
grid布局中的fr,支持transition,但是需额外套一层容器,兼容chrome(107+), safari(16+)
.grid{ display: grid; grid-template-rows: 0fr; transition: .3s; overflow: hidden; /*防止文字溢出*/ } .grid>div{ min-height: 0; /*防止文字撑开容器*/ } .wrap:hover .grid{ grid-template-rows: 1fr; }
方法4
使用mask-size, 支持transition,缺点同样是占据空间
.commentc{ transition: .3s; mask: linear-gradient(red,red) top no-repeat; mask-size: 100% 0%; } .commentc.fold { mask-size: 100% 100%; }
方法5
使用js实现,兼容性更好,其中也包含了一些技巧
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>Document</title> </head> <style> * { padding: 0; margin: 0; } ul { width: 200px; height: 0; /* 动画类型 */ transition: transform; /* 动画时长 */ transition-duration: .8s; /* 动画延迟 */ transition-delay: .2s; /* 动画控制属性 */ transition-property: height; overflow: hidden; cursor: pointer; border-radius: 2px; box-shadow: 6px 6px 10px rgba(0, 0, 0, 0.2); } li { list-style-type: none; width: 200px; height: 40px; line-height: 40px; color: #fff; font-size: 14px; text-align: center; background: #1061f8; } body { display: flex; flex-direction: column; align-items: center; } #btn { width: 200px; height: 40px; line-height: 40px; margin-top: 100px; text-align: center; background: #dfdfdf; border-radius: 2px; cursor: pointer; } </style> <body> <p id="btn">toggle菜单</p> <ul id="ul"> <li>菜单一</li> <li>菜单一</li> <li>菜单一</li> <li>菜单一</li> <li>菜单一</li> <li>菜单一</li> <li>菜单一</li> <li>菜单一</li> <li>菜单一</li> </ul> </body> <script> var btn = document.getElementById('btn'); var menu = document.getElementById('ul'); var heigt = 0 btn.onmouseenter = function () { // 获取菜单高度(执行JS时浏览器来不及渲染,所有不会闪烁) if (!heigt) { menu.style.height = 'auto'; heigt = menu.getBoundingClientRect().height; } menu.style.height = 0; //offsetHeight会强制浏览器重绘(先渲染0px,然后再渲染heigt,如果不加则直接会渲染height,不会渲染0px) menu.offsetHeight menu.style.height = heigt + 'px'; } btn.onmouseleave = function () { menu.style.height = 0; } menu.onmouseenter = function () { menu.style.height = heigt + 'px'; } menu.onmouseleave = function () { menu.style.height = 0; } </script> </html>
出处: