Illustrated CSS3 hub with colorful icons orbiting in a circle
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">&lt;/&gt;</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-state for 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: hidden or 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.