
本文详解如何仅用 CSS 实现 4×4 网格中按对角线顺序(1→4、2→3)逐个翻转、淡出、重置并无限循环的动画序列,无需 JavaScript,核心在于精确控制多段关键帧时序与 animation-iteration-count: infinite 的协同设计。
本文详解如何仅用 css 实现 4×4 网格中按对角线顺序(1→4、2→3)逐个翻转、淡出、重置并无限循环的动画序列,无需 javascript,核心在于精确控制多段关键帧时序与 `animation-iteration-count: infinite` 的协同设计。
要实现真正无限循环的 staggered(交错)翻转动画——即:显示全部方块 → 对角线成对翻转并消失(1&4 → 2&3)→ 全部重置为初始状态 → 重复整个流程——关键不在于叠加多个独立动画,而在于将整个周期统一为一个固定时长的完整动画循环,并通过百分比关键帧精细调度每个元素在周期内的行为。
本方案采用 5 秒为一个完整周期(animation-duration: 5s),将整个流程划分为清晰阶段:
- 0%–10%:第 1 个方块开始翻转(Y 轴旋转 180°)
- 20%–30%:第 4 个方块翻转;同时 30%–40%,1 & 4 淡出(opacity → 0)
- 40%–50%:第 2 个方块翻转
- 60%–70%:第 3 个方块翻转;70%–79.99%,2 & 3 淡出
- 79.99%–80%:所有方块瞬间“复位”(transform 归零 + backface-visibility 重置)
- 80%–90%:全部方块淡入(opacity → 1),完成重置
- 90%–100%:短暂静默,为下一轮循环做准备
✅ 为何用 79.99% 而非 80%?
避免关键帧边界冲突。CSS 动画在相同比例点定义不同状态时可能产生渲染歧义。将“淡出结束”设为 79.99%,而“复位动作”严格从 80% 开始,确保状态切换原子性。
以下是核心 CSS 关键帧定义(已精简注释,突出逻辑):
/* 第1个方块翻转动画:0%启动,10%完成翻转,79.99%保持翻转态,80%复位 */
@keyframes flip_1 {
0% { transform: none; backface-visibility: hidden; }
10%, 79.99% { transform: rotateY(180deg); backface-visibility: visible; }
80% { transform: none; backface-visibility: hidden; }
}
/* 第4个方块翻转:延迟启动,20%开始 */
@keyframes flip_4 {
20% { transform: none; backface-visibility: hidden; }
30%, 79.99% { transform: rotateY(180deg); backface-visibility: visible; }
80% { transform: none; backface-visibility: hidden; }
}
/* 1&4 共享淡入/淡出动画 */
@keyframes fade_1_4 {
30% { opacity: 1; } /* 淡出起点 */
40%, 80% { opacity: 0; } /* 淡出终点 & 淡入起点 */
90% { opacity: 1; } /* 淡入终点 */
}
/* 同理定义 flip_2 / flip_3 / fade_2_3,时序依次后移 */
@keyframes flip_2 {
40% { transform: none; backface-visibility: hidden; }
50%, 79.99% { transform: rotateY(180deg); backface-visibility: visible; }
80% { transform: none; backface-visibility: hidden; }
}
@keyframes flip_3 {
60% { transform: none; backface-visibility: hidden; }
70%, 79.99% { transform: rotateY(180deg); backface-visibility: visible; }
80% { transform: none; backface-visibility: hidden; }
}
@keyframes fade_2_3 {
70% { opacity: 1; }
79.99%, 80% { opacity: 0; }
90% { opacity: 1; }
}
在 HTML 结构不变的前提下,通过 CSS 选择器精准绑定动画:
/* 为每个方块指定专属翻转动画 */
.flip-card:nth-child(1) .flip-card-inner { animation: flip_1 5s infinite; }
.flip-card:nth-child(4) .flip-card-inner { animation: flip_4 5s infinite; }
.flip-card:nth-child(2) .flip-card-inner { animation: flip_2 5s infinite; }
.flip-card:nth-child(3) .flip-card-inner { animation: flip_3 5s infinite; }
/* 为成对元素绑定共享淡出/淡入动画 */
.flip-card:nth-child(1),
.flip-card:nth-child(4) { animation: fade_1_4 5s infinite; }
.flip-card:nth-child(2),
.flip-card:nth-child(3) { animation: fade_2_3 5s infinite; }
⚠️ 重要注意事项:
- transform-style: preserve-3d 和 perspective 必须保留在父容器 .flip-card 上,否则 3D 翻转失效;
- 所有 .flip-card-inner 的 transition: transform 0.5s 应移除或设为 none,避免与 animation 冲突导致抖动;
- 若需适配响应式尺寸,建议将 height/width 改为 aspect-ratio: 1 / 1 + min-block-size,提升可维护性;
- 此方案完全依赖 CSS 时间轴,不触发任何 JS 事件或 DOM 操作,性能极高,且天然支持 prefers-reduced-motion 媒体查询降级。
最终效果:动画如呼吸般自然循环——四格亮起 → 左上&右下同步翻转后隐去 → 右上&左下翻转隐去 → 全部瞬时复位并淡入 → 重新开始。整个过程平滑、可控、零 JS,是纯 CSS 动画编排能力的典型实践。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











