仅用CSS实现4x4网格方块无限对角线翻转消失动画
纯CSS实现2x2网格方块对角线翻转+隐藏的无限循环动画
我正在制作一个2x2网格方块的对角线逐个翻转动画,目前已实现以下效果:
- 方块可按需求单独翻转
- 点击两个方块后它们会消失
- 点击另外两个方块后,整个网格消失
现在需要实现无限循环动画,具体序列要求:
- 显示所有4个方块
- 将方块1和4顺时针对角线翻转,延迟后隐藏它们
- 对方块2和3重复上述翻转并隐藏的操作
- 所有方块隐藏后,重新显示未翻转的所有方块并重启序列
如何仅使用CSS实现这个带方块消失效果的无限循环动画?以下是我的现有代码:
* { box-sizing: border-box; } body { margin: 0; font-family: system-ui, sans-serif; color: black; background-color: rgb(19, 18, 18); } @keyframes tileFlipShow { from { backface-visibility: hidden; } to { transform: rotateY(180deg); backface-visibility: visible; } } @keyframes tileFlipHide { from { transform: rotateY(180deg); backface-visibility: visible; } to { backface-visibility: hidden; } } @keyframes hideTile { from { opacity: 1; } to { opacity: 0; } } .grid-container { display: grid; justify-content: center; align-items: center; height: 100vh; } .tile-grid { display: grid; grid-gap: 1px; grid-template-columns: repeat(2, 1fr); max-width: fit-content; } .tile-grid>div:nth-child(1) { animation-delay: 1.5s; } .tile-grid>div:nth-child(1) .flip-card-inner { animation-delay: 0s; } .tile-grid>div:nth-child(4) { animation-delay: 1.5s; } .tile-grid>div:nth-child(4) .flip-card-inner { animation-delay: 1s; } .tile-grid>div:nth-child(2) { animation-delay: 3.5s; } .tile-grid>div:nth-child(2) .flip-card-inner { animation-delay: 2s; } .tile-grid>div:nth-child(3) { animation-delay: 3.5s; } .tile-grid>div:nth-child(3) .flip-card-inner { animation-delay: 3s; } .flip-card { perspective: 1000px; margin: 1px; cursor: pointer; height: 9.375rem; width: 9.375rem; min-width: 3.125rem; min-height: 3.125rem; max-height: 9.375rem; max-width: 9.375rem; font-size: 1em; transition: all 0.2s ease-in-out; animation: 0.5s hideTile both; } .flip-card-inner { width: 100%; height: 100%; transform-style: preserve-3d; transition: transform 0.5s; animation: 0.5s tileFlipShow both; } .flip-card-front { height: 100%; width: 100%; position: absolute; backface-visibility: hidden; background-color: #3498db; color: #fff; display: flex; align-items: center; justify-content: center; font-size: 1.2rem; } .flip-card-front * { padding: 0; margin: 0; max-width: 100%; max-height: 100%; color: #fff; } .flip-card-back { height: 100%; width: 100%; position: absolute; backface-visibility: hidden; background-image: linear-gradient(-45deg, #ffc796 0%, #ff6b95 100%); backdrop-filter: blur(10rem); transform: rotateY(180deg); display: flex; align-items: center; justify-content: center; } .flip-card-back * { padding: 0; margin: 0; max-width: 100%; max-height: 100%; color: #fff; } .flip-card-back img { width: auto; height: 90%; } .flip-card-back picture { width: auto; height: 90%; } .flip-card-matched { visibility: hidden; } .flip-counter { position: absolute; top: 0; right: 0; z-index: 1; font-size: 0.5rem; display: none; }
<!DOCTYPE html> <html lang="en"> <head> <title>Bootstrap 5 example</title> <meta charset="UTF-8" /> <meta name="viewport" content="width=device-width" /> <link rel="stylesheet" href="styles.css" /> </head> <body> <div class="container"> <div class="grid-container"> <div class="tile-grid"> <div class="flip-card"> <div class="flip-card-inner not-matched"> <div class="flip-card-front">1</div> <div class="flip-card-back">11</div> </div> </div> <div class="flip-card"> <div class="flip-card-inner not-matched"> <div class="flip-card-front">2</div> <div class="flip-card-back">22</div> </div> </div> <div class="flip-card"> <div class="flip-card-inner not-matched"> <div class="flip-card-front">3</div> <div class="flip-card-back">22</div> </div> </div> <div class="flip-card"> <div class="flip-card-inner not-matched"> <div class="flip-card-front">4</div> <div class="flip-card-back">11</div> </div> </div> </div> </div> </div> </body> </html>
解决方案
要实现纯CSS无限循环,需调整动画的时长、循环属性,将翻转和隐藏整合为连贯的循环序列,确保每个方块的动画周期与整体循环同步。
修改后的完整代码
CSS 代码
* { box-sizing: border-box; } body { margin: 0; font-family: system-ui, sans-serif; color: black; background-color: rgb(19, 18, 18); } /* 整合翻转+隐藏的完整循环动画 */ @keyframes flipAndHide { 0% { opacity: 1; transform: rotateY(0deg); } 10% { /* 开始翻转 */ transform: rotateY(180deg); } 30% { /* 保持翻转状态 */ transform: rotateY(180deg); } 40% { /* 开始隐藏 */ opacity: 0; transform: rotateY(180deg); } 90% { /* 保持隐藏 */ opacity: 0; transform: rotateY(180deg); } 95% { /* 重置为初始状态(未翻转、显示) */ opacity: 1; transform: rotateY(0deg); } 100% { opacity: 1; transform: rotateY(0deg); } } .grid-container { display: grid; justify-content: center; align-items: center; height: 100vh; } .tile-grid { display: grid; grid-gap: 1px; grid-template-columns: repeat(2, 1fr); max-width: fit-content; } /* 方块1的动画:总周期8s,延迟0s */ .tile-grid > div:nth-child(1) .flip-card-inner { animation: flipAndHide 8s infinite both; } /* 方块4的动画:总周期8s,延迟0.5s(和方块1错开一点) */ .tile-grid > div:nth-child(4) .flip-card-inner { animation: flipAndHide 8s 0.5s infinite both; } /* 方块2的动画:总周期8s,延迟3s(等1、4隐藏后开始) */ .tile-grid > div:nth-child(2) .flip-card-inner { animation: flipAndHide 8s 3s infinite both; } /* 方块3的动画:总周期8s,延迟3.5s(和方块2错开一点) */ .tile-grid > div:nth-child(3) .flip-card-inner { animation: flipAndHide 8s 3.5s infinite both; } .flip-card { perspective: 1000px; margin: 1px; cursor: pointer; height: 9.375rem; width: 9.375rem; min-width: 3.125rem; min-height: 3.125rem; max-height: 9.375rem; max-width: 9.375rem; font-size: 1em; opacity: 1; /* 初始显示 */ } .flip-card-inner { width: 100%; height: 100%; transform-style: preserve-3d; } .flip-card-front { height: 100%; width: 100%; position: absolute; backface-visibility: hidden; background-color: #3498db; color: #fff; display: flex; align-items: center; justify-content: center; font-size: 1.2rem; } .flip-card-front * { padding: 0; margin: 0; max-width: 100%; max-height: 100%; color: #fff; } .flip-card-back { height: 100%; width: 100%; position: absolute; backface-visibility: hidden; background-image: linear-gradient(-45deg, #ffc796 0%, #ff6b95 100%); backdrop-filter: blur(10rem); transform: rotateY(180deg); display: flex; align-items: center; justify-content: center; } .flip-card-back * { padding: 0; margin: 0; max-width: 100%; max-height: 100%; color: #fff; } .flip-card-back img { width: auto; height: 90%; } .flip-card-back picture { width: auto; height: 90%; } .flip-card-matched { visibility: hidden; } .flip-counter { position: absolute; top: 0; right: 0; z-index: 1; font-size: 0.5rem; display: none; }
HTML 代码(无需修改)
<!DOCTYPE html> <html lang="en"> <head> <title>Bootstrap 5 example</title> <meta charset="UTF-8" /> <meta name="viewport" content="width=device-width" /> <link rel="stylesheet" href="styles.css" /> </head> <body> <div class="container"> <div class="grid-container"> <div class="tile-grid"> <div class="flip-card"> <div class="flip-card-inner not-matched"> <div class="flip-card-front">1</div> <div class="flip-card-back">11</div> </div> </div> <div class="flip-card"> <div class="flip-card-inner not-matched"> <div class="flip-card-front">2</div> <div class="flip-card-back">22</div> </div> </div> <div class="flip-card"> <div class="flip-card-inner not-matched"> <div class="flip-card-front">3</div> <div class="flip-card-back">22</div> </div> </div> <div class="flip-card"> <div class="flip-card-inner not-matched"> <div class="flip-card-front">4</div> <div class="flip-card-back">11</div> </div> </div> </div> </div> </div> </body> </html>
关键改动说明
- 整合动画关键帧:将翻转和隐藏合并为一个
flipAndHide动画,定义完整循环周期,包含显示→翻转→保持翻转→隐藏→保持隐藏→重置显示的全过程。 - 设置无限循环:给动画添加
infinite属性,实现自动重复。 - 同步动画周期:所有方块使用相同的总动画时长(8s),通过
animation-delay控制触发时机,确保序列连贯:- 方块1和4先触发翻转,间隔0.5s错开,模拟逐个翻转效果
- 方块2和3在1、4隐藏后(延迟3s)触发,同样间隔0.5s错开
- 移除冲突动画:删除原有的
tileFlipShow、hideTile等独立动画,避免冲突,统一使用整合后的循环动画。 - 重置初始状态:在动画的95%-100%阶段将方块重置为未翻转、完全显示的状态,为下一轮循环做准备。
内容的提问来源于stack exchange,提问作者Kannan Suresh
相关产品推荐
相关产品推荐

