Rockets climb and burst into double rings of sparks that sag and fade over a night sky, in four hues. Each burst is one element whose box-shadow sparks spread out as it scales up.
Also known as: css fireworks animation, fireworks night background, celebration background css.
<div class="bgx-fireworks" aria-hidden="true"><span></span><span></span><span></span><span></span></div>
.bgx-fireworks {
--c: var(--bgx-color, #3b82f6);
font-size: var(--bgx-size, 16px);
position: absolute;
inset: 0;
overflow: hidden;
background: linear-gradient(to bottom, #04050d, #0b0f24 65%, color-mix(in srgb, var(--c) 30%, #141a38));}
.bgx-fireworks span {
position: absolute;
top: var(--y);
left: var(--x);
color: var(--k);
}
.bgx-fireworks span::before {
content: "";
position: absolute;
width: 0.24em;
height: 0.24em;
margin: -0.12em;
border-radius: 50%;
rotate: var(--r);
box-shadow:
4.48em 0em 0 0.03em currentColor,
3.86em 0em 0 -0.02em color-mix(in srgb, currentColor 70%, transparent),
3.23em 0em 0 -0.05em color-mix(in srgb, currentColor 40%, transparent),
4.06em 1.96em 0 0.03em currentColor,
3.49em 1.69em 0 -0.02em color-mix(in srgb, currentColor 70%, transparent),
2.92em 1.41em 0 -0.05em color-mix(in srgb, currentColor 40%, transparent),
3.38em 2.93em 0 0.03em currentColor,
2.91em 2.52em 0 -0.02em color-mix(in srgb, currentColor 70%, transparent),
2.43em 2.11em 0 -0.05em color-mix(in srgb, currentColor 40%, transparent),
2.02em 3.95em 0 0.03em currentColor,
1.73em 3.4em 0 -0.02em color-mix(in srgb, currentColor 70%, transparent),
1.45em 2.85em 0 -0.05em color-mix(in srgb, currentColor 40%, transparent),
0.39em 4.67em 0 0.03em currentColor,
0.33em 4.02em 0 -0.02em color-mix(in srgb, currentColor 70%, transparent),
0.28em 3.36em 0 -0.05em color-mix(in srgb, currentColor 40%, transparent),
-1.31em 4.3em 0 0.03em currentColor,
-1.12em 3.7em 0 -0.02em color-mix(in srgb, currentColor 70%, transparent),
-0.94em 3.1em 0 -0.05em color-mix(in srgb, currentColor 40%, transparent),
-2.28em 3.34em 0 0.03em currentColor,
-1.96em 2.87em 0 -0.02em color-mix(in srgb, currentColor 70%, transparent),
-1.64em 2.4em 0 -0.05em color-mix(in srgb, currentColor 40%, transparent),
-3.27em 2.69em 0 0.03em currentColor,
-2.81em 2.32em 0 -0.02em color-mix(in srgb, currentColor 70%, transparent),
-2.35em 1.94em 0 -0.05em color-mix(in srgb, currentColor 40%, transparent),
-3.83em 1.09em 0 0.03em currentColor,
-3.29em 0.94em 0 -0.02em color-mix(in srgb, currentColor 70%, transparent),
-2.76em 0.79em 0 -0.05em color-mix(in srgb, currentColor 40%, transparent),
-4.44em -0.52em 0 0.03em currentColor,
-3.82em -0.45em 0 -0.02em color-mix(in srgb, currentColor 70%, transparent),
-3.2em -0.38em 0 -0.05em color-mix(in srgb, currentColor 40%, transparent),
-4.04em -2em 0 0.03em currentColor,
-3.47em -1.72em 0 -0.02em color-mix(in srgb, currentColor 70%, transparent),
-2.91em -1.44em 0 -0.05em color-mix(in srgb, currentColor 40%, transparent),
-3.11em -3.36em 0 0.03em currentColor,
-2.68em -2.89em 0 -0.02em color-mix(in srgb, currentColor 70%, transparent),
-2.24em -2.42em 0 -0.05em color-mix(in srgb, currentColor 40%, transparent),
-1.94em -4.03em 0 0.03em currentColor,
-1.67em -3.47em 0 -0.02em color-mix(in srgb, currentColor 70%, transparent),
-1.39em -2.9em 0 -0.05em color-mix(in srgb, currentColor 40%, transparent),
-0.71em -4.77em 0 0.03em currentColor,
-0.61em -4.1em 0 -0.02em color-mix(in srgb, currentColor 70%, transparent),
-0.51em -3.43em 0 -0.05em color-mix(in srgb, currentColor 40%, transparent),
0.99em -4.21em 0 0.03em currentColor,
0.85em -3.62em 0 -0.02em color-mix(in srgb, currentColor 70%, transparent),
0.71em -3.03em 0 -0.05em color-mix(in srgb, currentColor 40%, transparent),
2.4em -3.65em 0 0.03em currentColor,
2.06em -3.14em 0 -0.02em color-mix(in srgb, currentColor 70%, transparent),
1.73em -2.63em 0 -0.05em color-mix(in srgb, currentColor 40%, transparent),
3.37em -2.81em 0 0.03em currentColor,
2.9em -2.41em 0 -0.02em color-mix(in srgb, currentColor 70%, transparent),
2.43em -2.02em 0 -0.05em color-mix(in srgb, currentColor 40%, transparent),
4.1em -1.12em 0 0.03em currentColor,
3.52em -0.96em 0 -0.02em color-mix(in srgb, currentColor 70%, transparent),
2.95em -0.81em 0 -0.05em color-mix(in srgb, currentColor 40%, transparent),
2.41em 0.65em 0 -0.02em color-mix(in srgb, currentColor, #fff 55%),
1.77em 1.77em 0 -0.02em color-mix(in srgb, currentColor, #fff 55%),
0.65em 2.41em 0 -0.02em color-mix(in srgb, currentColor, #fff 55%),
-0.65em 2.41em 0 -0.02em color-mix(in srgb, currentColor, #fff 55%),
-1.77em 1.77em 0 -0.02em color-mix(in srgb, currentColor, #fff 55%),
-2.41em 0.65em 0 -0.02em color-mix(in srgb, currentColor, #fff 55%),
-2.41em -0.65em 0 -0.02em color-mix(in srgb, currentColor, #fff 55%),
-1.77em -1.77em 0 -0.02em color-mix(in srgb, currentColor, #fff 55%),
-0.65em -2.41em 0 -0.02em color-mix(in srgb, currentColor, #fff 55%),
0.65em -2.41em 0 -0.02em color-mix(in srgb, currentColor, #fff 55%),
1.77em -1.77em 0 -0.02em color-mix(in srgb, currentColor, #fff 55%),
2.41em -0.65em 0 -0.02em color-mix(in srgb, currentColor, #fff 55%),
0 0 1.6em 0.8em color-mix(in srgb, currentColor 30%, transparent);
opacity: 0;
animation:
bgx-fireworks-burst var(--dur) var(--delay) infinite,
bgx-fireworks-sag var(--dur) var(--delay) infinite;
}
.bgx-fireworks span::after {
content: "";
position: absolute;
top: 0;
left: -0.06em;
width: 0.12em;
height: 3em;
border-radius: 999em;
background: linear-gradient(to bottom, color-mix(in srgb, currentColor, #fff 50%), transparent);
opacity: 0;
animation: bgx-fireworks-launch var(--dur) var(--delay) infinite;
}
.bgx-fireworks span:nth-child(1) { --x: 22%; --y: 40%; --r: 0deg; --k: var(--c); --dur: 3.2s; --delay: -1.4s; }
.bgx-fireworks span:nth-child(2) { --x: 48%; --y: 34%; --r: 40deg; --k: oklch(from var(--c) 0.84 0.16 calc(h + 140)); --dur: 3.6s; --delay: -0.4s; }
.bgx-fireworks span:nth-child(3) { --x: 72%; --y: 46%; --r: 75deg; --k: oklch(from var(--c) 0.86 0.15 calc(h - 120)); --dur: 3.4s; --delay: -2.9s; }
.bgx-fireworks span:nth-child(4) { --x: 88%; --y: 30%; --r: 20deg; --k: oklch(from var(--c) 0.8 0.17 calc(h + 60)); --dur: 3.8s; --delay: -2.2s; }
@keyframes bgx-fireworks-sag {
0%, 60% { translate: 0 0; }
100% { translate: 0 1.4em; }
}
@keyframes bgx-fireworks-launch {
0% { transform: translateY(10em); opacity: 0; animation-timing-function: cubic-bezier(0.2, 0.6, 0.4, 1); }
4% { opacity: 1; }
26% { transform: translateY(0); opacity: 1; }
30% { transform: translateY(0) scaleY(0.2); opacity: 0; }
100% { transform: translateY(0) scaleY(0.2); opacity: 0; }
}
@keyframes bgx-fireworks-burst {
0%, 26% { transform: scale(0.05); opacity: 0; }
28% { opacity: 1; animation-timing-function: cubic-bezier(0.1, 0.7, 0.3, 1); }
70% { transform: scale(1); opacity: 1; }
100% { transform: scale(1.08); opacity: 0; }
}
@media (prefers-reduced-motion: reduce) {
.bgx-fireworks, .bgx-fireworks *, .bgx-fireworks::before, .bgx-fireworks::after, .bgx-fireworks *::before, .bgx-fireworks *::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.