Solar system
Pure CSSOrbits are rings on a tilted plane, each spinning at its own speed. Every planet undoes both rotations, so it always faces the camera.
Identical frames fly from far away to past the camera on staggered negative delays.
Your edited version
translateZ(-1400px) → translateZ(320px).animation-delay of i × (duration / count) spreads them evenly along the tunnel.animated translateZnegative animation-delayopacity fade-in at distance<div class="tunnel">
<i style="--i:0"></i>
<i style="--i:1"></i>
<i style="--i:2"></i>
<i style="--i:3"></i>
<i style="--i:4"></i>
<i style="--i:5"></i>
<i style="--i:6"></i>
<i style="--i:7"></i>
<i style="--i:8"></i>
<i style="--i:9"></i>
</div>
.tunnel {
position: fixed;
inset: 0;
display: grid;
place-items: center;
overflow: hidden;
perspective: 320px;
background: radial-gradient(circle, #1b0f3a, #05030d 70%);
}
.tunnel i {
position: absolute;
width: 260px;
height: 260px;
border: 3px solid hsl(calc(260 + var(--i) * 14) 90% 65%);
border-radius: 18px;
box-shadow: 0 0 18px hsl(calc(260 + var(--i) * 14) 90% 65% / 0.7);
animation: fly 4s linear infinite;
animation-delay: calc(var(--i) * -0.4s); /* 4s / 10 frames */
}
/* stop well before z = perspective (320px): the scale there is infinite */
@keyframes fly {
from { opacity: 0; transform: translateZ(-1400px) rotateZ(0deg); }
25%, 85% { opacity: 1; }
to { opacity: 0; transform: translateZ(200px) rotateZ(90deg); }
}
@use 'sass:math';
$frames: 10;
$duration: 4s;
.d-tunnel {
position: absolute;
inset: 0;
display: grid;
place-items: center;
overflow: hidden;
perspective: 320px;
background: radial-gradient(circle, #1b0f3a, #05030d 70%);
i {
position: absolute;
width: 200px;
height: 200px;
border: 3px solid hsl(calc(260 + var(--i) * 14) 90% 65%);
border-radius: 18px;
box-shadow: 0 0 18px hsl(calc(260 + var(--i) * 14) 90% 65% / 0.7);
animation: d-tunnel-fly $duration linear infinite;
// Spread the frames evenly across one loop. --i is 0…9 from the markup.
animation-delay: calc(var(--i) * #{math.div(-$duration, $frames)});
}
}
@keyframes d-tunnel-fly {
from {
opacity: 0;
transform: translateZ(-1400px) rotateZ(0deg);
}
25%,
85% {
opacity: 1;
}
// Perspective is 320px, so z = 200px already magnifies 2.7x (the frame is off-screen).
// Never animate up to z = perspective: the scale there is infinite.
to {
opacity: 0;
transform: translateZ(200px) rotateZ(90deg);
}
}