Orbit Loader
A clean circular loader with a small dot orbiting around the center. It uses only HTML and CSS, so it stays lightweight and easy to reuse.
<div class="orbit-loader" aria-label="Loading">
<span></span>
</div>
.orbit-loader{
position:relative;
width:70px;
height:70px;
border:2px solid rgba(34,211,238,.2);
border-radius:50%;
}
.orbit-loader span{
position:absolute;
top:50%;
left:50%;
width:12px;
height:12px;
margin:-6px;
border-radius:50%;
background:#22d3ee;
box-shadow:0 0 16px rgba(34,211,238,.75);
animation:orbitSpin 1.4s linear infinite;
}
@keyframes orbitSpin{
from{
transform:rotate(0deg) translateX(35px) rotate(0deg);
}
to{
transform:rotate(360deg) translateX(35px) rotate(-360deg);
}
}
How This Orbit Loader Works
The Orbit Loader is a CSS-only loading indicator built from one circular container and a single <span> element. The outer element creates the orbit path, while the inner span acts as a glowing dot that travels around that path continuously. There is no JavaScript in this component, so the animation is handled entirely by CSS.
The .orbit-loader container is 70px wide and 70px high. It uses position: relative, which provides the positioning reference for the animated span inside it. A 2px border with rgba(34,211,238,.2) creates the faint circular orbit line.
The container also uses border-radius: 50%. Because its width and height are equal, this turns the 70px square into a circle. The low-opacity cyan border stays visible throughout the animation and gives the moving dot a clear path to follow.
The inner span is positioned absolutely at top: 50% and left: 50%. This places its starting position at the exact center of the orbit container. The dot itself is 12px wide and 12px high, and border-radius: 50% turns it into a circle.
A margin: -6px shifts the dot upward and left by half of its own dimensions. This adjustment ensures that the center of the 12px dot aligns with the center point of the parent element instead of positioning its top-left corner there.
The dot uses a cyan #22d3ee background and a box-shadow of 0 0 16px rgba(34,211,238,.75). Since the shadow has no horizontal or vertical offset, the glow spreads evenly around the dot. The relatively high .75 opacity makes the moving point stand out clearly against the lighter orbit border.
The actual orbital movement comes from the orbitSpin keyframes. The animation lasts 1.4s, uses a linear timing function, and repeats infinitely. A linear timing function is useful here because the dot should move around the circular path at a consistent speed.
At the beginning of the animation, the transform is rotate(0deg) translateX(35px) rotate(0deg). The first rotation establishes the angle around the center point, while translateX(35px) moves the dot outward from the center. Since the container has a 70px diameter, 35px corresponds to its radius.
At the end of the animation, the transform becomes rotate(360deg) translateX(35px) rotate(-360deg). The first rotation moves the translated dot through one complete circle around the center. The negative final rotation counteracts the outer rotation applied to the element itself.
This combination of rotation and translation is a common way to create orbital movement without manually calculating positions around a circle. For more detail about functions such as rotate() and translateX(), see the MDN CSS transform documentation.
The parent element also includes aria-label="Loading". This gives the visual loader a short accessible description even though no visible loading text appears inside it.
Customizing the Orbit Loader
The component can be adjusted through its existing dimensions, border values, colors, glow settings, and animation timing.
- Change the
70pxwidth and height to make the complete orbit larger or smaller. - Adjust the
2pxborder width to make the circular path more or less prominent. - Change the
.2alpha value in the border color to control how visible the orbit line appears. - Modify the dot’s
12pxwidth and height to create a smaller or larger orbiting point. - Replace
#22d3eewith another color to match your interface. - Adjust the
16pxbox-shadow blur or.75opacity to change the strength of the glow. - Change
translateX(35px)to alter the radius of the dot’s orbit. - Modify the
1.4sanimation duration to make the dot orbit faster or slower.
Where to Use the Orbit Loader
This loader is useful for interfaces that need to indicate ongoing activity without showing an exact completion percentage.
- Dashboard widgets while remote data is being fetched.
- Form submissions during server-side processing.
- Modal windows that are waiting for asynchronous content.
- Full-page loading states with a centered indicator.
- Cards or panels that load independently.
- Compact interfaces where a circular loader fits better than a horizontal progress bar.
For another circular loading effect that uses multiple animated points instead of one orbiting dot, the Chasing Dots Loader is a related CodeRipple component worth considering. The Orbit Loader works particularly well when you want continuous motion with very little HTML and no JavaScript.
Frequently Asked Questions
Does the Orbit Loader use JavaScript?
No. The component contains no JavaScript. Its circular path, glowing dot, and orbital movement are all created with HTML and CSS.
How does the dot move in a circle?
The animation combines rotate() with translateX(35px). Translation moves the dot away from the center, while rotation moves that offset position around the parent element.
Why is the translateX value 35px?
The loader is 70px wide and high, so 35px is its radius. Moving the dot 35px from the center places it along the circular path.
How can I make the orbit animation faster?
Reduce the current 1.4s animation duration. A shorter duration makes the dot complete each full orbit more quickly, while a longer duration slows it down.
The Orbit Loader uses one container, one glowing dot, and a transform-based animation to create a compact circular loading indicator with minimal markup.
