如何为带有grid布局的div实现显示隐藏时的平滑缩放动画
解决方案
问题核心原因
- CSS transition 无法对
unset这类非明确数值的属性值生成过渡动画,是显示/隐藏时无平滑效果的核心原因 - 边框、内边距仅在可见态定义,隐藏时会直接跳变到0值,无过渡
- 网格列使用auto布局、未限制文字换行,会导致缩放过程中文字位置偏移、内容自动折行
调整后的完整代码
CSS代码
.ovdInfobox { display: grid; /* 固定网格布局,行高列宽比例固定,避免缩放时布局跳动 */ grid: 40px auto / 1fr 1fr; z-index: 1; position: absolute; top: 50px; /* 初始态明确设为0数值,支持过渡 */ width: 0; height: 0; min-width: 0; min-height: 0; overflow: hidden; /* 内边距初始为0,明确数值支持过渡 */ padding: 0; /* 预先定义边框样式,仅宽度为0,支持边框过渡 */ border: 0 solid #d1d1d1; background: rgba(255, 255, 255, 0.98); border-radius: 4px; font-family: inherit; font-size: inherit; line-height: inherit; transition: all 0.3s ease-in-out; /* 原代码4.2s为测试效果,可自行调整为正常的0.2-0.3s */ background: green; /* 禁止所有文字换行,保证位置固定 */ white-space: nowrap; } .ovdInfobox--visible { /* 用明确的数值定义最终宽高,不要用unset */ min-width: 300px; min-height: 120px; /* 根据实际内容高度设置,比实际高度稍大即可 */ border-width: 1px; padding: 15px; /* 需要内边距时直接开启即可,会自动生成过渡效果 */ } .ovdInfobox__header { grid-column-start: span 2; color: #c20063; font-size: 18px; font-weight: normal; } .ovdInfobox__label { font-weight: bold; } .ovdInfobox__data {}
JS代码(无需修改)
function toggle() { if (document.getElementsByClassName("ovdInfobox")[0].classList.contains("ovdInfobox--visible")) { document.getElementsByClassName("ovdInfobox")[0].classList.remove("ovdInfobox--visible") console.log('remove'); } else { document.getElementsByClassName("ovdInfobox")[0].classList.add("ovdInfobox--visible") console.log('add'); } }
HTML代码(无需修改)
<div> <button onclick="toggle()"> Click Me! </button> <div class="ovdInfobox ovdInfobox--visible" onCLick="toggle()"> <div class="ovdInfobox__header">Details</div> <div class="ovdInfobox__label"> label </div> <div class="ovdInfobox__data"> data </div> <div class="ovdInfobox__label"> label </div> <div class="ovdInfobox__data"> data </div> </div> </div>
关键调整说明
- 所有参与过渡的属性都在初始态和可见态定义了明确的数值,保证transition可以生成插值动画
- 网格布局固定比例,搭配
white-space: nowrap,缩放过程中文字位置不会偏移、不会自动折行,超出容器部分自动裁剪 - 边框、内边距都加入过渡队列,隐藏时不会出现突然跳变的问题
内容的提问来源于stack exchange,提问作者pcvnes
相关产品推荐
相关产品推荐

