Fireflies drift and blink above dark hills at dusk, some near and bright, some small and far away. Wandering runs on translate and blinking on opacity, so the two never sync up.
Also known as: fireflies css animation, glowing particles background, firefly night background.
<div class="bgx-fireflies" 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></div>
.bgx-fireflies {
--c: var(--bgx-color, #3b82f6);
font-size: var(--bgx-size, 16px);
position: absolute;
inset: 0;
overflow: hidden;
--glow: color-mix(in oklab, var(--c) 30%, #eaff8a);
background:
radial-gradient(ellipse 55% 30% at 18% 106%, #03060a 97%, transparent),
radial-gradient(ellipse 75% 26% at 84% 108%, #050a0f 97%, transparent),
linear-gradient(to bottom, #04070f 10%, color-mix(in srgb, var(--c) 30%, #0b1a1a));}
.bgx-fireflies span {
position: absolute;
top: var(--y);
left: var(--x);
width: var(--s);
height: var(--s);
border-radius: 50%;
background: color-mix(in srgb, var(--glow), #fff 40%);
box-shadow: 0 0 calc(var(--s) * 2) calc(var(--s) * 0.6) color-mix(in srgb, var(--glow) 55%, transparent);
opacity: 0.1;
animation:
bgx-fireflies-wander var(--dur) ease-in-out var(--delay) infinite,
bgx-fireflies-blink var(--blink) ease-in-out var(--delay) infinite;
}
.bgx-fireflies span:nth-child(1) { --x: 92.7%; --y: 76.5%; --s: 0.26em; --ax: -1.23em; --ay: 0.98em; --dur: 6.16s; --blink: 3.41s; --delay: -7.48s; }
.bgx-fireflies span:nth-child(2) { --x: 46.9%; --y: 75.8%; --s: 0.35em; --ax: 1.79em; --ay: 1.43em; --dur: 9.26s; --blink: 3.76s; --delay: -3.67s; }
.bgx-fireflies span:nth-child(3) { --x: 38.8%; --y: 22.7%; --s: 0.32em; --ax: 1.23em; --ay: 0.98em; --dur: 8.11s; --blink: 2.44s; --delay: -5.17s; }
.bgx-fireflies span:nth-child(4) { --x: 57.9%; --y: 20.8%; --s: 0.25em; --ax: 1.51em; --ay: 1.21em; --dur: 7.52s; --blink: 3.95s; --delay: -3.01s; }
.bgx-fireflies span:nth-child(5) { --x: 16%; --y: 65.3%; --s: 0.22em; --ax: -2.26em; --ay: 1.81em; --dur: 9.62s; --blink: 3.02s; --delay: -1.99s; }
.bgx-fireflies span:nth-child(6) { --x: 70.3%; --y: 32.9%; --s: 0.28em; --ax: -1.76em; --ay: 1.41em; --dur: 8.41s; --blink: 2.37s; --delay: -7.68s; }
.bgx-fireflies span:nth-child(7) { --x: 64.2%; --y: 25.5%; --s: 0.4em; --ax: 1.83em; --ay: 1.46em; --dur: 6.45s; --blink: 2.27s; --delay: -4.85s; }
.bgx-fireflies span:nth-child(8) { --x: 51%; --y: 83.4%; --s: 0.36em; --ax: -2.38em; --ay: 1.9em; --dur: 6.35s; --blink: 3.13s; --delay: -7.91s; }
.bgx-fireflies span:nth-child(9) { --x: 27.3%; --y: 40.5%; --s: 0.18em; --ax: 2.3em; --ay: 1.84em; --dur: 6.42s; --blink: 2.12s; --delay: -1.36s; }
.bgx-fireflies span:nth-child(10) { --x: 84.5%; --y: 27.3%; --s: 0.38em; --ax: -1.24em; --ay: 0.99em; --dur: 6.01s; --blink: 3.01s; --delay: -2.07s; }
.bgx-fireflies span:nth-child(11) { --x: 97.9%; --y: 60%; --s: 0.23em; --ax: 1.1em; --ay: 0.88em; --dur: 6.53s; --blink: 3.31s; --delay: -2.95s; }
.bgx-fireflies span:nth-child(12) { --x: 36.2%; --y: 23.8%; --s: 0.23em; --ax: 1.45em; --ay: 1.16em; --dur: 8.81s; --blink: 2.54s; --delay: -2.08s; }
.bgx-fireflies span:nth-child(13) { --x: 24%; --y: 37.4%; --s: 0.34em; --ax: -1.7em; --ay: 1.36em; --dur: 6.5s; --blink: 2.25s; --delay: -7.37s; }
.bgx-fireflies span:nth-child(14) { --x: 10.2%; --y: 44.6%; --s: 0.34em; --ax: 1.65em; --ay: 1.32em; --dur: 6.23s; --blink: 2.37s; --delay: -4.98s; }
.bgx-fireflies span:nth-child(15) { --x: 76.9%; --y: 79.4%; --s: 0.25em; --ax: -2.33em; --ay: 1.86em; --dur: 8.8s; --blink: 3.77s; --delay: -2.06s; }
.bgx-fireflies span:nth-child(16) { --x: 3.3%; --y: 59.9%; --s: 0.28em; --ax: 1.39em; --ay: 1.11em; --dur: 6.43s; --blink: 2.53s; --delay: -7.82s; }
@keyframes bgx-fireflies-wander {
0%, 100% { translate: 0 0; }
25% { translate: var(--ax) calc(var(--ay) * -1); }
50% { translate: calc(var(--ax) * 0.3) calc(var(--ay) * 0.7); }
75% { translate: calc(var(--ax) * -0.7) calc(var(--ay) * -0.3); }
}
@keyframes bgx-fireflies-blink {
0%, 100% { opacity: 0.1; transform: scale(0.7); }
45% { opacity: 1; transform: scale(1); }
60% { opacity: 0.85; }
}
@media (prefers-reduced-motion: reduce) {
.bgx-fireflies, .bgx-fireflies *, .bgx-fireflies::before, .bgx-fireflies::after, .bgx-fireflies *::before, .bgx-fireflies *::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.