求助:用HTML和CSS Keyframes实现盒子折叠展开动画遇阻
盒子折叠展开动画实现问题
我正尝试利用HTML和CSS的@keyframes实现如图所示的盒子折叠展开动画,但陷入了困境。调整过旋转和transform属性后,始终无法达到预期效果——盒子需要向内折叠隐藏文本“Hi”,再向外展开重新显示该文本。盒子颜色不是问题,核心是动画效果无法实现。
动画预期效果:
当前编写的代码如下:
HTML代码
<div class="container"> <div class="group left"> <div class="box topleft steelblue"></div> <div class="box bottomleft yellow"></div> </div> <div class="space">Hi</div> <div class="group right"> <div class="box topright diegray"></div> <div class="box bottomright rosybrown"></div> </div> </div>
CSS代码
/* styles.css */ .container { display: flex; justify-content: center; align-items: center; height: 400px; } .group { display: flex; flex-direction: column; justify-content: center; width: 200px; margin: 0 15px; } .topleft { width: 100px; height: 75px; border-radius: 10px; margin: 0 auto; transform-origin: bottom left; } .topright { width: 100px; height: 75px; border-radius: 10px; margin: 0 auto; transform-origin: bottom left; } .bottomleft { width: 100px; height: 75px; border-radius: 10px; margin: 0 auto; transform-origin: bottom right; } .bottomright { width: 100px; height: 75px; border-radius: 10px; margin: 0 auto; transform-origin: bottom left; } .topleft { background-color: steelblue; animation: rotateTopLeft 2s linear infinite; } .topright { background-color: steelblue; animation: rotateTopRight 2s linear infinite; } .bottomleft { background-color: steelblue; animation: rotateTopLeft 2s linear infinite; } .bottomright { background-color: steelblue; animation: rotateTopRight 2s linear infinite; } @keyframes rotateTopLeft { 0% { transform: rotate(0deg); } 100% { transform: rotate(-90deg); } } @keyframes rotateTopRight { 0% { transform: rotate(0deg); } 100% { transform: rotate(-90deg); } } @keyframes rotateBottomLeft { 0% { transform: rotate(0deg); } 100% { transform: rotate(90deg); } } @keyframes rotateBottomRight { 0% { transform: rotate(0deg); } 100% { transform: rotate(-90deg); } } .bottomleft { background-color: yellow; } .topright { background-color: rosybrown; } .topright { background-color: diegray; } .space { width: 100px; height: 75px; display: flex; justify-content: center; align-items: center; font-size: 24px; }
问题分析与修正方案
原代码存在几个关键问题:
transform-origin设置错误,导致盒子旋转方向不符合预期- 动画关键帧未正确绑定到对应元素(比如bottomleft误用了rotateTopLeft动画)
- CSS存在重复属性定义(比如topright多次设置背景色)
- 元素布局未让盒子能完全覆盖中间的“Hi”区域
- 动画缺少往返效果(当前仅单向旋转,无展开动作)
修正后的完整代码
<div class="container"> <div class="group left"> <div class="box topleft"></div> <div class="box bottomleft"></div> </div> <div class="space">Hi</div> <div class="group right"> <div class="box topright"></div> <div class="box bottomright"></div> </div> </div>
.container { display: flex; justify-content: center; align-items: center; height: 400px; position: relative; } .group { display: flex; flex-direction: column; width: 100px; position: relative; } .box { width: 100px; height: 75px; border-radius: 10px; position: absolute; backface-visibility: hidden; } .topleft { background-color: steelblue; transform-origin: bottom left; animation: foldTopLeft 2s ease-in-out infinite alternate; top: 0; } .topright { background-color: dimgray; transform-origin: bottom right; animation: foldTopRight 2s ease-in-out infinite alternate; top: 0; } .bottomleft { background-color: yellow; transform-origin: top left; animation: foldBottomLeft 2s ease-in-out infinite alternate; bottom: 0; } .bottomright { background-color: rosybrown; transform-origin: top right; animation: foldBottomRight 2s ease-in-out infinite alternate; bottom: 0; } .space { width: 100px; height: 150px; display: flex; justify-content: center; align-items: center; font-size: 24px; z-index: -1; } @keyframes foldTopLeft { 0% { transform: rotate(0deg); } 100% { transform: rotate(-90deg); } } @keyframes foldTopRight { 0% { transform: rotate(0deg); } 100% { transform: rotate(90deg); } } @keyframes foldBottomLeft { 0% { transform: rotate(0deg); } 100% { transform: rotate(90deg); } } @keyframes foldBottomRight { 0% { transform: rotate(0deg); } 100% { transform: rotate(-90deg); } }
关键修改说明
- 布局调整:将
.group宽度改为100px,盒子设置为绝对定位,确保四个盒子能刚好覆盖中间的“Hi”区域 - transform-origin修正:每个盒子设置正确的旋转原点,比如左上盒子以左下角为原点旋转,右上盒子以右下角为原点旋转
- 动画往返效果:使用
infinite alternate让动画在折叠和展开之间循环 - 层级调整:给
.space设置z-index: -1,确保盒子折叠时能覆盖文本 - CSS清理:移除重复的属性定义,统一管理样式
内容的提问来源于stack exchange,提问作者Dan
相关产品推荐
相关产品推荐

