Multi Orbit
A white sun in the middle of three very faint rings, and five planets of 6 to 14 px all turning the same way in 3, 5 and 8 s, paired in opposition on the outer orbits: a small system with several rhythms, in pure CSS with offset-path: circle(), frozen and readable when the user reduces motion.
Updated
This effect is part of Effect.Labs — 840 vanilla effects, some free, some premium. 3D has 50 effects, including 8 free. Explore the category →
3 usage examples



How it works
The .fx-0038-root block is at least 300 px high and takes the full available width, background #0a0a0f. In the middle, .mp-multiorbit-scene (260 × 260 px) holds three rings of 100, 160 and 220 px (white border at 6%, nearly invisible), a 30 px white sun with a glow, and five planets in position: absolute. The sun sits in front (z-index: 2).
Each planet follows a circle centered on the scene: offset-path: circle(50px), circle(80px) or circle(110px), which it rides by its center, traveled by the mpOrbit animation (offset-distance from 0 to 100%, linear, clockwise, starting at 3 o'clock). The inner orbit carries the 14 px red planet (3 s per lap), the middle orbit a 10 px yellow one and a 12 px cyan one (5 s), the outer orbit an 8 px green one and a 6 px purple one (8 s). On the two shared orbits, the second planet has a negative delay of half a period (-2.5s, -4s): it starts already halfway around, opposite its neighbor, and stays there.
Ground speeds are close (about 105, 100 and 86 px per second): it is the laps that differ, not the pace, as with planets. The starting layout only comes back after 120 s (the least common multiple of 3, 5 and 8), so the eye never sees a loop. No script, no id: two copies of the block on a page each run on their own (measured). Under prefers-reduced-motion: reduce, a block scoped to .fx-0038-root removes the animations and sets the five planets at fixed places (15, 40, 90, 70 and 20% of their orbit), the pairs still facing each other.
Accessibility
- Reduced motion: under
prefers-reduced-motion: reduce, the five planets stop, spread out on their orbits, instead of piling up at the starting point. Measured in Chromium, Firefox and WebKit: 0 running animations, 0% of pixels change in 800 ms. - Decorative content: there is no text in the drawing. If it illustrates lines or rounds, put
aria-hidden="true"on the root and give the information as text next to it (one legend entry per color, as in the examples). - Color alone: the planets differ by color and a little by size (6 to 14 px). If the legend relies on color, write each line's name in plain text; the smallest planets (6 and 8 px) are hard to see on a phone screen in bright sunlight.
- No interaction: the effect reacts to neither mouse, finger nor keyboard, and takes no focus.
Browser compatibility
Pure CSS: offset-path: circle(), animated offset-distance, negative animation-delay, prefers-reduced-motion. No dependency, no JavaScript. Measured in Chromium 151, Firefox 153 and WebKit 26.5: each planet stays within 0.1 px of its circle, same periods, same stop under reduced motion, two independent copies on the page.
Without offset-path: circle(), the five planets stay in the center, hidden behind the sun (measured by removing the property): you see a sun and its rings, still, with nothing broken.
The code
HTML structure to paste into your page (the CSS + JS come with your purchase):
<div class="fx-0038-root">
<div class="mp-multiorbit-scene">
<div class="mp-multiorbit-ring mp-multiorbit-ring--1"></div> <!-- 100 px -->
<div class="mp-multiorbit-ring mp-multiorbit-ring--2"></div> <!-- 160 px -->
<div class="mp-multiorbit-ring mp-multiorbit-ring--3"></div> <!-- 220 px -->
<div class="mp-multiorbit-center"></div>
<div class="mp-multiorbit-planet mp-multiorbit-planet--1"></div> <!-- circle(50px), 3 s -->
<div class="mp-multiorbit-planet mp-multiorbit-planet--2"></div> <!-- circle(80px), 5 s -->
<div class="mp-multiorbit-planet mp-multiorbit-planet--3"></div> <!-- circle(80px), 5 s, -2.5 s -->
<div class="mp-multiorbit-planet mp-multiorbit-planet--4"></div> <!-- circle(110px), 8 s -->
<div class="mp-multiorbit-planet mp-multiorbit-planet--5"></div> <!-- circle(110px), 8 s, -4 s -->
</div>
</div>
One-time payment, no subscription — the code is yours forever
Customize
Options passed to the API or data-* attributes:
| Option / property | Default | Effect |
|---|---|---|
Lap duration (CSS — animation of each .mp-multiorbit-planet--N) |
3 s, 5 s and 8 s | Keep both planets of an orbit at the same duration, or one catches up with the other and the pair breaks. Durations without a small common multiple delay the return of the starting layout. |
Opposition on an orbit (CSS — negative animation-delay) |
-2.5s on 5 s, -4s on 8 s |
Half a period puts the planet opposite its neighbor. For three evenly spaced planets on a 6 s orbit: 0, -2s and -4s. |
Orbit radius (CSS — offset-path: circle(50px), 80px, 110px) |
50, 80 and 110 px | Also change the ring size (diameter = twice the radius: 100, 160, 220 px). To enlarge everything, prefer transform: scale() on .mp-multiorbit-scene. |
Ring visibility (CSS — border of .mp-multiorbit-ring) |
white at 6% | Go up to 20-30% to show the routes (shuttle lines, rounds); on a light background, switch to a dark color. |
Planet size (CSS — width and height) |
14, 10, 12, 8 and 6 px | Change width and height: the planet stays centered on its ring whatever its size. The negative margin in the code has no effect on the path (measured with a 24 px planet). |
Colors (CSS — background and box-shadow) |
red, yellow, cyan, green, purple; white sun | Each planet's glow is a box-shadow in its hue at 50%: change both together. |
FAQ
offset-path: circle(), but for two different stories. Orbit Circle (free) plays on direction: a purple core, two clearly visible dashed rings, three dots, two of which cross head-on on the same ring. Multi Orbit plays on period: a white sun, three nearly faded rings, five planets all turning the same way at three rhythms, paired in opposition. Pick Orbit Circle to show two flows crossing; Multi Orbit to show several frequencies around the same center (shuttles, rounds, a solar system).perspective or preserve-3d. A transform: rotateX(60deg) on .mp-multiorbit-scene squashes the circles into ellipses, but it squashes the planets too, which turn into ovals. For orbits seen at an angle with round planets, you would need elliptical paths (offset-path: ellipse()) in a flat plane.