Blog
This tutorial rebuilds the classic circular rotate animation with responsive CSS3. A fixed hub stays centered while satellites travel around it on circular tracks. The effect uses CSS transforms and keyframes, and JavaScript is only needed for optional custom controls.
How the circular animation works
An orbit is a positioned circle that rotates through one full turn. A satellite sits at its top edge, so it travels around the center as its parent rotates. The hub is a separate sibling and does not move. Percentage-based insets make the track responsive instead of relying on viewport coordinates.
Step 1: Create the orbit structure
Place each satellite inside its own orbit and keep the hub outside the animated tracks.
<div class="orbit-stage">
<div class="orbit" aria-hidden="true">
<span class="satellite"></></span>
</div>
<div class="orbit orbit--inner" aria-hidden="true">
<span class="satellite">✦</span>
</div>
<div class="hub">CSS3</div>
</div>
Step 2: Set the stage and orbit radius
Use a square stage and CSS Grid to center the hub. Set each orbit’s radius with an inset percentage, then position its satellite at the top center.
.orbit-stage {
position: relative;
width: min(100%, 32rem);
aspect-ratio: 1;
display: grid;
place-items: center;
}
.orbit {
position: absolute;
inset: 12%;
border: 1px solid #4388ff66;
border-radius: 50%;
animation: orbit 18s linear infinite;
}
.orbit--inner {
inset: 27%;
animation-duration: 14s;
animation-direction: reverse;
}
.satellite {
position: absolute;
top: 0;
left: 50%;
transform: translate(-50%, -50%);
}
Step 3: Animate a full turn
A linear timing function keeps the angular speed steady. One full turn returns the satellite to its starting point.
@keyframes orbit { to { transform: rotate(1turn); } }
Responsive and reduced motion
Keep the stage fluid with width: min(100%, 32rem) and aspect-ratio: 1. Use clamp() for satellite sizes on narrow screens. Respect a visitor’s motion preference with this rule:
@media (prefers-reduced-motion: reduce) {
.orbit { animation: none; }
}
Customize the effect
- Increase the duration to slow the orbit down; lower it to speed up the lap.
- Change the inset to move satellites closer to or farther from the hub.
- Use negative animation delays to spread several satellites around the circle.
- Counter-rotate icons if they should remain upright while orbiting.
- Toggle
animation-play-statefor a pause control.
Common troubleshooting
- If nothing moves, check that the animation name matches the keyframes and the orbit has a non-zero size.
- If the path looks oval, ensure the stage is square and the orbit uses
border-radius: 50%. - If a satellite is clipped, remove
overflow: hiddenor move it slightly inward.
Frequently asked questions
Does the effect need JavaScript?
No. CSS keyframes create the orbit. JavaScript is optional for custom controls such as pause, reverse, or speed changes.
How can I add more items?
Add satellites with different negative animation delays, or use separate orbit elements with different start rotations.
Live Demo
Use the controls below to pause the animation, reverse direction, or switch to a slower lap.
Conclusion
CSS transforms make circular movement responsive and easy to reuse. Download the self-contained project for the full demo, touch-friendly controls, and reduced-motion support.
CSS animation playground
Circular Orbit Animation
Two satellites move around a steady CSS3 hub. Pause the motion, reverse the direction, or slow the orbit down.
Animation is running at normal speed.