Border-trick Ring Spinner
A square with border-radius: 50% turns into a ring; side-specific border colors do the rest. Three variants: a classic single-arc, a counter-rotating dual ring, and a two-tone two-halves loop.
A square with border-radius: 50% turns into a ring; side-specific border colors do the rest. Three variants: a classic single-arc, a counter-rotating dual ring, and a two-tone two-halves loop.
Spinner / border-trick / ring
Reimplements the classic CSS spinner with a rounded square and side-specific border colors, then extends the primitive into a dual-ring counter-rotation and a two-tone halves variant.
Three transparent sides + one accent
A square with 50% border-radius becomes a ring. Coloring a single border side produces the classic quarter-segment spinner.
Two rings + opposite spin
A pseudo-element ring sits inset from the outer ring and rotates the opposite way. The counter-rotation adds mechanical weight without moving the layout.
Two colored halves + steady spin
Two opposing border sides take contrasting hues. The ring reads as a full loop but the color split gives the rotation a visible reference point.
A CSS ring spinner uses a square box, equal border thickness, border-radius: 50%, and one accent border side rotated with transform.
1<div class="ring-spinner-status" role="status" aria-live="polite"><span class="ring-spinner" aria-hidden="true"></span><span>Loading</span></div><style>.ring-spinner-status {display: inline-flex;align-items: center;gap: .75rem;color: #cbd5e1;font: 600 .95rem/1.2 ui-sans-serif, system-ui;}14.ring-spinner {display: inline-block;box-sizing: border-box;inline-size: 3.25rem;18aspect-ratio: 1;border: .42rem solid rgba(103, 232, 249, .18);20border-block-start-color: rgba(103, 232, 249, .96);border-radius: 50%;22animation: ring-spinner-recipe-spin .9s linear infinite;}@keyframes ring-spinner-recipe-spin {25to { transform: rotate(1turn); }}@media (prefers-reduced-motion: reduce) {.ring-spinner { animation: none; }}</style>
Usually no. Mark the spinner aria-hidden and expose loading through adjacent text, aria-busy on the region, or a polite live region. The rotating border is not the semantic loading state.
Same width: 54px and border: 7px on both. box-sizing: content-box adds the border outside the box, so the spinner balloons to ~68px outer diameter. box-sizing: border-box keeps the outer diameter at exactly 54px — the layout footprint stays stable as you tune the border thickness.
The element is probably not square, border widths differ, or box-sizing is changing the outer size. Use aspect-ratio: 1, equal border thickness, and box-sizing: border-box.
The element is probably not square, border widths differ, or box-sizing is changing the outer size. Use aspect-ratio: 1, equal border thickness, and box-sizing: border-box.
A colored square border spins like a box; border-radius turns the same geometry into a circular loading ring.
Yes. Border, border-radius, and transform rotation are broadly supported. It is a good fallback when conic-gradient or masking is not available.
A small transform-rotated element is cheap. Problems come from rendering many indefinite spinners at once or adding heavy shadows and filters around each loader.
The classic CSS border-trick spinner: a square with border-radius: 50% becomes a ring, and giving one side a colored border (the other three transparent) produces a quarter-segment that rotates. Extends naturally into dual-ring counter-rotations and two-tone halves variants without adding any new mechanism — just more border manipulation.
Reach for border-trick spinners when you need a spinner that works in legacy browsers without conic-gradient support (back to Chrome 4, Safari 5). Skip the dual-ring variant inside small UI — the inner counter-rotation is lost below ~24px diameter. Skip border-trick entirely if you have flexible color stops; conic-gradient produces tapered ends that read more refined.
Set the element to a fixed square size (e.g. 32px x 32px), apply border: 3px solid transparent; border-top-color: var(--accent); border-radius: 50% and rotate it with animation: spin 1s linear infinite. The result is a ring with a single visible quarter-arc rotating. For dual rings, nest a second spinner inside with the opposite animation-direction: reverse. For the two-tone halves variant, set two adjacent border sides to different colors so the rotating arc reads as complementary halves rather than a single tail.
The border-trick spinner ages well in legacy browsers but cannot produce gradient or tapered tail ends; if your design needs those, reach for SVG or conic-gradient instead. Sub-pixel border widths produce jagged edges on non-retina displays — stick to integer pixel values. Animations stutter when the spinner is rendered inside an overflow: hidden ancestor with a transformed sibling because of compositor layer promotion races; add transform: translateZ(0) on the spinner to force its own layer.
Pair with role="status" + aria-label like the conic spinner. Under prefers-reduced-motion: reduce drop the animation entirely and replace with a static loading-shape SVG so the visual signal remains. The spinner color should hit at least 3:1 contrast against the background or it disappears for low-vision users.
Border-ring spinners rely on simple geometry: a circular box, side-specific border colors, and rotation. Pseudo-elements can add counter-rotating layers without adding extra DOM.
Watch border thickness at small sizes. A ring that looks crisp at 48px can collapse at 16px, so test dense UI sizes and provide reduced motion that shows a static ring rather than a blank gap.