Paper confetti in four hues flutters down a light backdrop, each piece flipping in 3D as it sways. Colors come from the accent with relative color syntax, so one variable retints it.
Also known as: css confetti background, falling confetti css, confetti animation css.
<div class="bgx-confetti" aria-hidden="true"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></div>
.bgx-confetti {
--c: var(--bgx-color, #3b82f6);
font-size: var(--bgx-size, 16px);
position: absolute;
inset: 0;
overflow: hidden;
background: linear-gradient(to bottom, color-mix(in srgb, var(--c) 6%, #fff), color-mix(in srgb, var(--c) 16%, #fff));}
.bgx-confetti span {
position: absolute;
top: 0;
left: var(--x);
height: 100%;
animation: bgx-confetti-fall var(--dur) linear var(--delay) infinite;
}
.bgx-confetti span::before {
content: "";
position: absolute;
top: 0;
left: 0;
width: 0.55em;
height: 0.95em;
border-radius: 0.08em;
background: var(--k);
animation:
bgx-confetti-flip var(--spin) linear infinite,
bgx-confetti-sway calc(var(--spin) * 1.6) ease-in-out infinite alternate;
}
.bgx-confetti span:nth-child(4n + 1) { --k: var(--c); }
.bgx-confetti span:nth-child(4n + 2) { --k: oklch(from var(--c) 0.78 0.17 calc(h + 150)); }
.bgx-confetti span:nth-child(4n + 3) { --k: oklch(from var(--c) 0.84 0.16 calc(h - 150)); }
.bgx-confetti span:nth-child(4n + 4) { --k: oklch(from var(--c) 0.7 0.2 calc(h + 70)); }
.bgx-confetti span:nth-child(3n)::before { width: 0.6em; height: 0.6em; border-radius: 50%; }
.bgx-confetti span:nth-child(5n)::before { width: 0.28em; height: 1.4em; }
.bgx-confetti span:nth-child(1) { --x: 29.9%; --dur: 7.47s; --delay: -4.42s; --spin: 1.63s; --ax: 0.44; }
.bgx-confetti span:nth-child(2) { --x: 93.9%; --dur: 5.21s; --delay: -5.85s; --spin: 1.56s; --ax: 0.99; }
.bgx-confetti span:nth-child(3) { --x: 5.8%; --dur: 4.86s; --delay: -2.21s; --spin: 1.39s; --ax: 0.64; }
.bgx-confetti span:nth-child(4) { --x: 20.5%; --dur: 4.97s; --delay: -5.95s; --spin: 1.62s; --ax: 0.36; }
.bgx-confetti span:nth-child(5) { --x: 18.2%; --dur: 7.37s; --delay: -1.55s; --spin: 1.31s; --ax: 0.31; }
.bgx-confetti span:nth-child(6) { --x: 99.3%; --dur: 7.11s; --delay: -5.68s; --spin: 1.63s; --ax: 0.65; }
.bgx-confetti span:nth-child(7) { --x: 85.6%; --dur: 5.41s; --delay: -2.38s; --spin: 1.08s; --ax: 0.9; }
.bgx-confetti span:nth-child(8) { --x: 78.7%; --dur: 5.21s; --delay: -1.17s; --spin: 0.9s; --ax: 0.86; }
.bgx-confetti span:nth-child(9) { --x: 9.7%; --dur: 5.64s; --delay: -5.92s; --spin: 1.34s; --ax: 0.22; }
.bgx-confetti span:nth-child(10) { --x: 40.7%; --dur: 6.35s; --delay: -1.23s; --spin: 1.76s; --ax: 0.48; }
.bgx-confetti span:nth-child(11) { --x: 90.9%; --dur: 5.64s; --delay: -1.23s; --spin: 1.01s; --ax: 0.63; }
.bgx-confetti span:nth-child(12) { --x: 83.9%; --dur: 5.8s; --delay: -4.4s; --spin: 1.1s; --ax: 0.62; }
.bgx-confetti span:nth-child(13) { --x: 59.9%; --dur: 4.51s; --delay: -1.82s; --spin: 1.72s; --ax: 0.87; }
.bgx-confetti span:nth-child(14) { --x: 62.1%; --dur: 7.29s; --delay: -1.62s; --spin: 1.5s; --ax: 0.48; }
.bgx-confetti span:nth-child(15) { --x: 37.6%; --dur: 5.01s; --delay: -1.25s; --spin: 1.71s; --ax: 0.77; }
.bgx-confetti span:nth-child(16) { --x: 32.9%; --dur: 5.31s; --delay: -6.12s; --spin: 0.96s; --ax: 0.25; }
.bgx-confetti span:nth-child(17) { --x: 24.1%; --dur: 6.88s; --delay: -2.91s; --spin: 1s; --ax: 0.4; }
.bgx-confetti span:nth-child(18) { --x: 75.6%; --dur: 7.42s; --delay: -2.98s; --spin: 1.07s; --ax: 0.88; }
.bgx-confetti span:nth-child(19) { --x: 47.4%; --dur: 4.63s; --delay: -5.09s; --spin: 1.35s; --ax: 0.41; }
.bgx-confetti span:nth-child(20) { --x: 52.8%; --dur: 6.77s; --delay: -3.67s; --spin: 1.38s; --ax: 0.5; }
.bgx-confetti span:nth-child(21) { --x: 56.3%; --dur: 7.13s; --delay: -0.79s; --spin: 1.34s; --ax: 0.81; }
.bgx-confetti span:nth-child(22) { --x: 71.4%; --dur: 5.36s; --delay: -3.78s; --spin: 0.95s; --ax: 0.91; }
.bgx-confetti span:nth-child(23) { --x: 66.5%; --dur: 5.87s; --delay: -0.36s; --spin: 1.54s; --ax: 0.86; }
.bgx-confetti span:nth-child(24) { --x: 12.6%; --dur: 6.69s; --delay: -4.89s; --spin: 1.03s; --ax: 0.42; }
.bgx-confetti span:nth-child(25) { --x: 44.6%; --dur: 4.85s; --delay: -0.59s; --spin: 0.99s; --ax: 0.7; }
.bgx-confetti span:nth-child(26) { --x: 2.3%; --dur: 6.48s; --delay: -4.07s; --spin: 1.4s; --ax: 0.23; }
@keyframes bgx-confetti-fall {
from { transform: translateY(-2em); }
to { transform: translateY(100%); }
}
@keyframes bgx-confetti-flip {
from { transform: rotate3d(1, var(--ax), 0.2, 0deg); }
to { transform: rotate3d(1, var(--ax), 0.2, 360deg); }
}
@keyframes bgx-confetti-sway {
from { translate: -0.8em 0; }
to { translate: 0.8em 0; }
}
@media (prefers-reduced-motion: reduce) {
.bgx-confetti, .bgx-confetti *, .bgx-confetti::before, .bgx-confetti::after, .bgx-confetti *::before, .bgx-confetti *::after {
animation-duration: 0.01ms !important;
animation-iteration-count: 1 !important;
transition-duration: 0.01ms !important;
}
}--bgx-color on the element or a parent.
Currently previewing #3b82f6.--bgx-size. Every other dimension is in
em, so the whole thing scales together. Currently previewing 16px.transition or animation
shorthand. Staggered delays are relative, so they keep their rhythm.