Pink petals ride a spring breeze diagonally across a pale sky, tumbling in 3D as they go. Each petal's carrier is the size of the background, so the diagonal holds in any container shape.
Also known as: sakura petals falling css, falling petals animation, cherry blossom petals css.
<div class="bgx-cherry-blossom" 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></div>
.bgx-cherry-blossom {
--c: var(--bgx-color, #3b82f6);
font-size: var(--bgx-size, 16px);
position: absolute;
inset: 0;
overflow: hidden;
--petal: color-mix(in oklab, var(--c) 15%, #ff9cc2);
background: linear-gradient(to bottom, color-mix(in srgb, var(--c) 14%, #fff), color-mix(in srgb, var(--petal) 24%, #fff));}
.bgx-cherry-blossom span {
position: absolute;
inset: 0;
left: calc(var(--x) - 45%);
animation: bgx-cherry-blossom-drift var(--dur) linear var(--delay) infinite;
}
.bgx-cherry-blossom span::before {
content: "";
position: absolute;
top: 0;
left: 0;
width: var(--s);
height: calc(var(--s) * 0.8);
border-radius: 50% 0 50% 50%;
background: linear-gradient(135deg, color-mix(in srgb, var(--petal) 25%, #fff), var(--petal) 65%);
animation:
bgx-cherry-blossom-tumble var(--spin) linear infinite,
bgx-cherry-blossom-gust calc(var(--spin) * 1.7) ease-in-out infinite alternate;
}
.bgx-cherry-blossom span:nth-child(1) { --x: 70.1%; --s: 1.21em; --dur: 9.7s; --delay: -4.65s; --spin: 2.01s; --ax: 0.36; }
.bgx-cherry-blossom span:nth-child(2) { --x: 5.7%; --s: 0.98em; --dur: 11.99s; --delay: -5.89s; --spin: 2.1s; --ax: 0.91; }
.bgx-cherry-blossom span:nth-child(3) { --x: 44.5%; --s: 1.17em; --dur: 8.93s; --delay: -9.51s; --spin: 2.97s; --ax: 0.83; }
.bgx-cherry-blossom span:nth-child(4) { --x: 93.8%; --s: 0.75em; --dur: 10.1s; --delay: -4.65s; --spin: 1.75s; --ax: 0.67; }
.bgx-cherry-blossom span:nth-child(5) { --x: 46.9%; --s: 1.05em; --dur: 7.31s; --delay: -5.4s; --spin: 2.46s; --ax: 0.57; }
.bgx-cherry-blossom span:nth-child(6) { --x: 85.4%; --s: 1.12em; --dur: 7.01s; --delay: -2.11s; --spin: 2.87s; --ax: 0.38; }
.bgx-cherry-blossom span:nth-child(7) { --x: 38%; --s: 0.87em; --dur: 8.01s; --delay: -0.82s; --spin: 2.62s; --ax: 0.71; }
.bgx-cherry-blossom span:nth-child(8) { --x: 50.9%; --s: 1.11em; --dur: 11.94s; --delay: -9.63s; --spin: 2.84s; --ax: 0.92; }
.bgx-cherry-blossom span:nth-child(9) { --x: 29.6%; --s: 1.12em; --dur: 9.1s; --delay: -6.57s; --spin: 2.19s; --ax: 0.98; }
.bgx-cherry-blossom span:nth-child(10) { --x: 66.2%; --s: 0.85em; --dur: 9.86s; --delay: -1.68s; --spin: 2.11s; --ax: 0.85; }
.bgx-cherry-blossom span:nth-child(11) { --x: 20.3%; --s: 1.29em; --dur: 11.01s; --delay: -11.16s; --spin: 1.62s; --ax: 0.85; }
.bgx-cherry-blossom span:nth-child(12) { --x: 14.6%; --s: 1.23em; --dur: 7.16s; --delay: -6.38s; --spin: 3.02s; --ax: 0.37; }
.bgx-cherry-blossom span:nth-child(13) { --x: 80.6%; --s: 0.95em; --dur: 8.71s; --delay: -5.19s; --spin: 1.95s; --ax: 0.72; }
.bgx-cherry-blossom span:nth-child(14) { --x: 33.3%; --s: 1.22em; --dur: 9.24s; --delay: -1.08s; --spin: 2.82s; --ax: 0.71; }
.bgx-cherry-blossom span:nth-child(15) { --x: 25%; --s: 0.97em; --dur: 8.48s; --delay: -1.76s; --spin: 1.79s; --ax: 0.86; }
.bgx-cherry-blossom span:nth-child(16) { --x: 57.8%; --s: 0.86em; --dur: 9.88s; --delay: -10.05s; --spin: 2.16s; --ax: 0.37; }
.bgx-cherry-blossom span:nth-child(17) { --x: 74.7%; --s: 0.97em; --dur: 10.69s; --delay: -10.06s; --spin: 3.07s; --ax: 0.83; }
.bgx-cherry-blossom span:nth-child(18) { --x: 90.2%; --s: 1.16em; --dur: 7.82s; --delay: -4.95s; --spin: 1.95s; --ax: 0.58; }
.bgx-cherry-blossom span:nth-child(19) { --x: 12%; --s: 1.1em; --dur: 10.33s; --delay: -8.81s; --spin: 1.63s; --ax: 0.89; }
.bgx-cherry-blossom span:nth-child(20) { --x: 60.8%; --s: 0.99em; --dur: 7.15s; --delay: -4.61s; --spin: 1.98s; --ax: 0.38; }
.bgx-cherry-blossom span:nth-child(21) { --x: 98.7%; --s: 1.08em; --dur: 7.93s; --delay: -9.71s; --spin: 2.56s; --ax: 0.72; }
.bgx-cherry-blossom span:nth-child(22) { --x: 3.2%; --s: 0.91em; --dur: 10.09s; --delay: -5.66s; --spin: 1.98s; --ax: 0.74; }
@keyframes bgx-cherry-blossom-drift {
from { transform: translate(-2em, -2em); }
to { transform: translate(60%, 100%); }
}
@keyframes bgx-cherry-blossom-tumble {
from { transform: rotate3d(1, var(--ax), 0.4, 0deg); }
to { transform: rotate3d(1, var(--ax), 0.4, 360deg); }
}
@keyframes bgx-cherry-blossom-gust {
from { translate: 0 -0.8em; }
to { translate: 0 0.8em; }
}
@media (prefers-reduced-motion: reduce) {
.bgx-cherry-blossom, .bgx-cherry-blossom *, .bgx-cherry-blossom::before, .bgx-cherry-blossom::after, .bgx-cherry-blossom *::before, .bgx-cherry-blossom *::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.