如何在CSS动画0%关键帧保留HTML元素折叠前尺寸【已解决】
实现折叠动画:获取元素折叠前的初始尺寸作为动画关键帧起点
核心问题
你没法直接在CSS动画的0%关键帧中“自动获取”元素修改属性前的尺寸——当data-space=collapsed生效时,元素的样式已经被覆盖。需要通过静态预设或动态捕获的方式拿到初始尺寸。
方案1:静态布局场景(尺寸固定)
如果你的#settings初始尺寸是固定的(8列×64px=512px宽,2行×64px=128px高),可以直接在动画关键帧里写死初始值,同时同步恢复初始布局属性,避免动画过程中布局跳变:
/* 基础样式保持不变 */ #settings { display: grid; grid-template-columns: repeat(8, 64px); grid-template-rows: repeat(2, 64px); } /* 折叠状态只负责触发动画,最终样式交给动画控制 */ #settings[data-space=collapsed] { /* 空出样式,由动画完成过渡 */ } /* 动画触发规则 */ #settings[data-space=collapsed][data-firstAnimation=false] { animation: collapseSettings 1s ease 0s 1 normal forwards; /* forwards 让动画结束后保持最终状态 */ } /* 动画关键帧 */ @keyframes collapseSettings { 0% { width: 512px; height: 128px; display: grid; grid-template-columns: repeat(8, 64px); grid-template-rows: repeat(2, 64px); } 100% { width: 50px; height: 50px; display: flex; justify-content: center; align-items: center; } }
方案2:动态布局场景(尺寸不固定)
如果#settings的初始尺寸是动态变化的(比如响应式、内容驱动),需要用JS先捕获元素修改属性前的实际尺寸,存入CSS变量后再在动画中使用:
步骤1:定义CSS变量与样式
#settings { --initial-width: auto; --initial-height: auto; display: grid; grid-template-columns: repeat(8, 64px); grid-template-rows: repeat(2, 64px); } /* 动画结束后应用最终样式 */ #settings[data-space=collapsed][data-firstAnimation=true] { width: 50px; height: 50px; display: flex; justify-content: center; align-items: center; } /* 动画触发规则 */ #settings[data-space=collapsed][data-firstAnimation=false] { animation: collapseSettings 1s ease 0s 1 normal forwards; } /* 使用CSS变量的动画关键帧 */ @keyframes collapseSettings { 0% { width: var(--initial-width); height: var(--initial-height); display: grid; grid-template-columns: repeat(8, 64px); grid-template-rows: repeat(2, 64px); } 100% { width: 50px; height: 50px; display: flex; justify-content: center; align-items: center; } }
步骤2:JS捕获初始尺寸并触发动画
const settingsEl = document.getElementById('settings'); // 切换折叠状态前,先获取当前计算后的宽高 const computedStyle = window.getComputedStyle(settingsEl); settingsEl.style.setProperty('--initial-width', computedStyle.width); settingsEl.style.setProperty('--initial-height', computedStyle.height); // 设置属性触发动画 settingsEl.setAttribute('data-space', 'collapsed'); settingsEl.setAttribute('data-firstAnimation', 'false'); // 动画结束后标记为已完成,避免重复触发 settingsEl.addEventListener('animationend', () => { settingsEl.setAttribute('data-firstAnimation', 'true'); });
内容的提问来源于stack exchange,提问作者EnolaK
相关产品推荐
相关产品推荐

