Three layers of stars drift upward at different speeds over a deep night sky, so the near stars pass the far ones. Each layer is one tiled gradient moved by exactly one tile.
Also known as: animated stars background css, moving stars background, parallax star background css.
<div class="bgx-parallax-starfield" aria-hidden="true"><span></span><span></span><span></span></div>
.bgx-parallax-starfield {
--c: var(--bgx-color, #3b82f6);
font-size: var(--bgx-size, 16px);
position: absolute;
inset: 0;
overflow: hidden;
background: radial-gradient(ellipse 140% 100% at 50% 125%, color-mix(in srgb, var(--c) 34%, #0a0f24), #03040b 72%);}
.bgx-parallax-starfield span {
position: absolute;
inset: 0 0 calc(var(--tile) * -1);
background-size: var(--tile) var(--tile);
animation: bgx-parallax-starfield-rise var(--dur) linear infinite;
}
.bgx-parallax-starfield span:nth-child(1) {
--tile: 9em;
--dur: 40s;
background-image:
radial-gradient(circle 0.07em at 4% 45.1%, rgb(255 255 255 / 0.6) 50%, transparent),
radial-gradient(circle 0.07em at 32.7% 8.2%, rgb(255 255 255 / 0.6) 50%, transparent),
radial-gradient(circle 0.07em at 83.2% 41.6%, rgb(255 255 255 / 0.6) 50%, transparent),
radial-gradient(circle 0.07em at 51.6% 47%, rgb(255 255 255 / 0.6) 50%, transparent),
radial-gradient(circle 0.07em at 47.4% 29.9%, rgb(255 255 255 / 0.6) 50%, transparent),
radial-gradient(circle 0.07em at 24.1% 69.6%, rgb(255 255 255 / 0.6) 50%, transparent),
radial-gradient(circle 0.07em at 16.9% 39%, rgb(255 255 255 / 0.6) 50%, transparent),
radial-gradient(circle 0.07em at 58.1% 80.1%, rgb(255 255 255 / 0.6) 50%, transparent),
radial-gradient(circle 0.07em at 39.2% 11.8%, rgb(255 255 255 / 0.6) 50%, transparent),
radial-gradient(circle 0.07em at 24% 71.6%, rgb(255 255 255 / 0.6) 50%, transparent),
radial-gradient(circle 0.07em at 58.5% 55%, rgb(255 255 255 / 0.6) 50%, transparent),
radial-gradient(circle 0.07em at 48% 25.6%, rgb(255 255 255 / 0.6) 50%, transparent);
}
.bgx-parallax-starfield span:nth-child(2) {
--tile: 14em;
--dur: 26s;
background-image:
radial-gradient(circle 0.11em at 4% 6.3%, color-mix(in srgb, var(--c) 25%, #fff) 50%, transparent),
radial-gradient(circle 0.11em at 38.9% 54.5%, color-mix(in srgb, var(--c) 25%, #fff) 50%, transparent),
radial-gradient(circle 0.11em at 27.3% 7.3%, color-mix(in srgb, var(--c) 25%, #fff) 50%, transparent),
radial-gradient(circle 0.11em at 11.5% 60.5%, color-mix(in srgb, var(--c) 25%, #fff) 50%, transparent),
radial-gradient(circle 0.11em at 61.4% 49.8%, color-mix(in srgb, var(--c) 25%, #fff) 50%, transparent),
radial-gradient(circle 0.11em at 79.5% 91.1%, color-mix(in srgb, var(--c) 25%, #fff) 50%, transparent),
radial-gradient(circle 0.11em at 14.3% 77.2%, color-mix(in srgb, var(--c) 25%, #fff) 50%, transparent),
radial-gradient(circle 0.11em at 25.1% 20.8%, color-mix(in srgb, var(--c) 25%, #fff) 50%, transparent),
radial-gradient(circle 0.11em at 44.2% 20.3%, color-mix(in srgb, var(--c) 25%, #fff) 50%, transparent);
}
.bgx-parallax-starfield span:nth-child(3) {
--tile: 21em;
--dur: 15s;
background-image:
radial-gradient(circle 0.34em at 4% 83.8%, #fff 0 22%, color-mix(in srgb, var(--c) 55%, transparent) 36%, transparent),
radial-gradient(circle 0.34em at 92.1% 93.2%, #fff 0 22%, color-mix(in srgb, var(--c) 55%, transparent) 36%, transparent),
radial-gradient(circle 0.34em at 69.5% 13.3%, #fff 0 22%, color-mix(in srgb, var(--c) 55%, transparent) 36%, transparent),
radial-gradient(circle 0.34em at 72.1% 14.9%, #fff 0 22%, color-mix(in srgb, var(--c) 55%, transparent) 36%, transparent),
radial-gradient(circle 0.34em at 16.3% 57.7%, #fff 0 22%, color-mix(in srgb, var(--c) 55%, transparent) 36%, transparent),
radial-gradient(circle 0.34em at 21.4% 24.1%, #fff 0 22%, color-mix(in srgb, var(--c) 55%, transparent) 36%, transparent);
}
@keyframes bgx-parallax-starfield-rise {
to { transform: translateY(calc(var(--tile) * -1)); }
}
@media (prefers-reduced-motion: reduce) {
.bgx-parallax-starfield, .bgx-parallax-starfield *, .bgx-parallax-starfield::before, .bgx-parallax-starfield::after, .bgx-parallax-starfield *::before, .bgx-parallax-starfield *::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.