这个 HTML 页面实现了一个动态、立体、色彩缤纷的彩纸(Confetti)飘落动画效果,常用于庆祝、成功提示或节日氛围营造。
大家复制代码时,可能会因格式转换出现错乱,导致样式失效。建议先少量复制代码进行测试,若未能解决问题,私信回复源码两字,我会发送完整的压缩包给你。
演示效果


HTML&CSS
html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>彩纸</title>
<style>
body {
margin: 0;
overflow: hidden;
background: #111;
perspective: 1000px;
}
.confetti {
position: absolute;
top: -50px;
transform-style: preserve-3d;
animation: fall linear forwards;
}
.piece {
position: relative;
transform-style: preserve-3d;
animation: spin linear infinite;
}
.side {
position: absolute;
width: 12px;
height: 18px;
backface-visibility: hidden;
}
.back {
transform: rotateY(180deg);
filter: brightness(0.6);
}
@keyframes fall {
0% {
transform:
translateY(0) translateZ(-800px) scale(0.3);
opacity: 0.8;
}
100% {
transform:
translateY(110vh) translateZ(300px) scale(1.4);
opacity: 1;
}
}
@keyframes spin {
0% {
transform: rotateX(0deg) rotateY(0deg) rotateZ(0deg);
}
100% {
transform: rotateX(720deg) rotateY(720deg) rotateZ(360deg);
}
}
</style>
</head>
<body>
<script>
const colors = [
"#ff0a54", "#ff477e", "#ff85a1",
"#00f5d4", "#9b5de5",
"#fee440", "#00bbf9"
];
function createConfetti() {
const confetti = document.createElement("div");
confetti.classList.add("confetti");
const piece = document.createElement("div");
piece.classList.add("piece");
const front = document.createElement("div");
const back = document.createElement("div");
front.classList.add("side");
back.classList.add("side", "back");
const color = colors[Math.floor(Math.random() * colors.length)];
front.style.background = color;
back.style.background = color;
piece.appendChild(front);
piece.appendChild(back);
confetti.appendChild(piece);
confetti.style.left = Math.random() * window.innerWidth + "px";
const fallDuration = Math.random() * 4 + 4;
const spinDuration = Math.random() * 3 + 2;
confetti.style.animationDuration = fallDuration + "s";
piece.style.animationDuration = spinDuration + "s";
document.body.appendChild(confetti);
setTimeout(() => {
confetti.remove();
}, fallDuration * 1000);
}
setInterval(createConfetti, 90);
</script>
</body>
</html>
HTML
- .confetti:每个彩纸的容器,控制整体下落动画。
- .piece:单个彩纸片,负责旋转动画。
- .side / .back:构成一个"双面"小矩形,模拟 3D 翻转效果。
CSS
1. 全局基础样式
css
body {
margin: 0;
overflow: hidden; /* 隐藏超出屏幕的彩纸,避免滚动条 */
background: #111; /* 深黑背景,突出彩色纸片 */
perspective: 1000px; /* 开启3D透视,数值越大透视感越弱,1000px是自然的3D效果 */
}
核心:
- perspective: 1000px 是 3D 特效的基础,让子元素的 3D 变换呈现「近大远小」的透视效果;
- overflow: hidden 保证彩纸超出屏幕后不可见,避免页面出现滚动条。
2. 彩纸核心层级样式(3D 结构)
css
/_ 彩纸容器:控制整体飘落轨迹 _/
.confetti {
position: absolute;
top: -50px; /_ 初始位置在屏幕上方外,模拟从顶部飘落 _/
transform-style: preserve-3d; /_ 保留子元素的 3D 变换,不扁平化 _/
animation: fall linear forwards; /_ 飘落动画:匀速,结束后保持最终状态 _/
}
/_ 彩纸本体:控制旋转 _/
.piece {
position: relative;
transform-style: preserve-3d; /_ 子元素(正反面)保留 3D 变换 _/
animation: spin linear infinite; /_ 旋转动画:匀速,无限循环 _/
}
/_ 彩纸正反面:立体面 _/
.side {
position: absolute;
width: 12px;
height: 18px; /_ 长方形纸片,更贴近真实彩纸 _/
backface-visibility: hidden; /_ 隐藏背面(旋转时不会看到透明的反面) _/
}
.back {
transform: rotateY(180deg); /_ 反面绕 Y 轴旋转 180°,与正面背对 _/
filter: brightness(0.6); /_ 反面调暗,模拟立体纸片的阴影感 _/
}
核心 3D 结构:
- transform-style: preserve-3d:必须给父元素设置,否则子元素的 3D 变换会被扁平化(失去立体效果);
- backface-visibility: hidden:避免旋转时看到纸片的「透明反面」,配合 rotateY(180deg) 实现「正反面分离」;
- 反面调暗(brightness(0.6)):模拟真实纸片的厚度 / 阴影,增强 3D 立体感。
3. 动画关键帧
css
/_ 飘落动画:从顶部到屏幕下方,伴随 3D 远近和缩放 _/
@keyframes fall {
0% {
transform: translateY(0) translateZ(-800px) scale(0.3); /_ 初始:远、小、顶部 _/
opacity: 0.8;
}
100% {
transform: translateY(110vh) translateZ(300px) scale(1.4); /_ 结束:近、大、超出屏幕下方 _/
opacity: 1;
}
}
/_ 旋转动画:3 轴同时旋转,模拟不规则飘落 _/
@keyframes spin {
0% {
transform: rotateX(0deg) rotateY(0deg) rotateZ(0deg);
}
100% {
transform: rotateX(720deg) rotateY(720deg) rotateZ(360deg); /_ X/Y 轴转 2 圈,Z 轴转 1 圈 _/
}
}
核心动画设计:
- 飘落动画(fall):translateZ 控制 3D 远近(初始远、结束近),scale 配合实现「近大远小」;translateY(110vh) 让彩纸落到屏幕下方外,模拟「落地消失」;
- 旋转动画(spin):X/Y/Z 三轴同时旋转,避免单一轴旋转的机械感,更贴近真实彩纸的不规则旋转;infinite 保证旋转持续到彩纸消失。
JavaScript
JS 的核心是「动态创建 + 随机化 + 自动清理」,实现无限且不规则的彩纸飘落效果。
js
// 1. 定义彩纸颜色数组:高饱和度亮色,视觉冲击力强
const colors = [
"#ff0a54", "#ff477e", "#ff85a1", // 粉色系
"#00f5d4", "#9b5de5", // 青/紫系
"#fee440", "#00bbf9" // 黄/蓝系
];
// 2. 创建单张彩纸的核心函数
function createConfetti() {
// 步骤1:创建彩纸DOM结构(层级:confetti → piece → front/back)
const confetti = document.createElement("div");
confetti.classList.add("confetti"); // 外层容器,控制飘落
const piece = document.createElement("div");
piece.classList.add("piece"); // 内层,控制旋转
const front = document.createElement("div");
const back = document.createElement("div");
front.classList.add("side");
back.classList.add("side", "back"); // 正反面
// 步骤2:随机选择颜色,设置正反面背景
const color = colors[Math.floor(Math.random() * colors.length)];
front.style.background = color;
back.style.background = color;
// 步骤3:组装DOM结构
piece.appendChild(front);
piece.appendChild(back);
confetti.appendChild(piece);
// 步骤4:随机化关键参数,避免特效重复
confetti.style.left = Math.random() * window.innerWidth + "px"; // 随机水平位置
const fallDuration = Math.random() * 4 + 4; // 飘落时长:4-8秒(随机)
const spinDuration = Math.random() * 3 + 2; // 旋转时长:2-5秒(随机)
// 步骤5:给动画设置随机时长
confetti.style.animationDuration = fallDuration + "s";
piece.style.animationDuration = spinDuration + "s";
// 步骤6:添加到页面
document.body.appendChild(confetti);
// 步骤7:自动清理元素(避免DOM堆积,优化性能)
setTimeout(() => {
confetti.remove(); // 飘落结束后删除元素
}, fallDuration * 1000); // 延迟时间 = 飘落时长(毫秒)
}
// 3. 定时创建彩纸:每90毫秒创建一张,形成连续飘落效果
setInterval(createConfetti, 90);
各位互联网搭子,要是这篇文章成功引起了你的注意,别犹豫,关注、点赞、评论、分享走一波,让我们把这份默契延续下去,一起在知识的海洋里乘风破浪!