Advertisement

Circular Variable Font Loading Spinner

| by Vladimir | 2 min read | code by David Aerne
Intermediate

Tech & Dependencies

HTML SCSS Babel

Features

  • Variable Typography
  • Radial Positioning
  • Staggered Animation

Browser Support

Chrome 92+ Edge 92+ Firefox 90+ Safari 15.4+

Core

This is a Circular Variable Font Loading Spinner. It arranges individual characters into a radial path, creating a sophisticated typographic loop. Its function is to serve as a high-fidelity alternative to standard SVG or icon-based loaders, utilizing the weight-axis of variable fonts to simulate organic growth and motion.

Specs

  • Weight: < 2 KB (Code only). Font weight depends on the loaded variable file.
  • Performance: High. All character movement and weight shifts are handled by the browser’s compositor thread using CSS transform and font-weight.
  • Theming / Customization: Easily adjustable radius (--r), duration (--t), and text content via the data-circletext attribute.
  • Responsiveness: Fluid. Relies on rem units and fixed positioning, keeping the spinner centered regardless of viewport size.
  • Graceful Degradation: Fails back to a standard single-weight font. In browsers without variable font support, the animation still works via opacity and transform, but loses the fluid weight shift.

Anatomy

The component operates as a bridge between a data attribute and a CSS-driven spatial grid.

  • HTML (The Skeleton): A singular div acting as a controller, carrying the source text in a data- attribute.
  • CSS (The Skin): Defines the radial geometry. It uses the Plex Sans VF variable font, allowing for a continuous spectrum between thin (100) and heavy (900) weights.
  • JS (The Nervous System): Orchestrates the setup. It parses the string, wraps each letter in tags, and injects a normalized index variable (--i) into the local CSS scope of each character.

Logic

The standout logic is the “Polar-to-Cartesian” coordinate translation hack within the transform property.

.t i {
  transform: translate(-50%,-50%) 
             rotate(calc(var(--i) * 360deg)) 
             translateY(calc(-1 * var(--r))) 
             rotate(calc(var(--i) * -360deg));
}

Instead of using complex absolute offsets, the CSS engine rotates the element, pushes it out along the Y-axis by the radius (--r), and then counter-rotates the inner character by the same amount to keep it upright. This allows a dynamic number of characters to always form a perfect circle based solely on the --i progress variable.

Feel

Mechanical but organic. The transition of the variable font-weight makes the text feel as if it is physically expanding and contracting as it passes through the focal point. The ease-in-out timing creates a rhythmic “breathing” effect that feels more polished than a static rotation.

Advertisement