Overview
An hourglass loader is an object-state loop rather than a simple spinner. This page compares two ways to close that loop: a real drain-pause-flip cycle that rotates the actual vessel, and a CSS-only fade reset that hides the refill jump. Both methods still need to behave like a compact UI loader: one fixed footprint, one status label, and no layout movement.
When to use it
Use this for short, indefinite waits where a little character is welcome: generating a report, preparing a preview, or waiting for a batch step to complete. Skip it in dense tables, navigation chrome, or repeated list rows where a circular spinner or native progress element scans faster. If the system knows real progress, use a determinate progress indicator instead of an hourglass loop.
How it works
The vessel sits in a fixed-size wrapper with transform-origin: center. The frame is an SVG hourglass, each bulb is clipped with clipPath, and the sand rectangles move with translateY(). In the real flip method, JavaScript waits for the drain phase, pauses, then rotates the vessel by 180 degrees. In the fade reset method, CSS keyframes keep the vessel upright and briefly fade the graphic while the sand jumps back to its starting state.
Production gotchas
The common failures are wrong pivot, visible reset jumps, and layout-sized sand. A top-origin rotation swings the vessel outside its box, so the loader clips or bumps into neighbors. Animating sand height can resize the row below it. Keep the wrapper dimensions stable, move clipped sand layers with transforms, and make the method explicit: either truly flip after the drain phase, or hide the reset with opacity.
Accessibility
The hourglass is decorative. Put the text state in a wrapper with role="status" and aria-live="polite", then mark the hourglass graphic aria-hidden. Reduced motion should freeze the vessel and sand in a clear pending state rather than swapping to another animation. Stop the loop when the real async state resolves, fails, or times out.
References
Implementation depth
An hourglass loader differs from circular spinners because it is an object-state loop: a fixed two-bulb vessel rotates around its center while clipped sand layers imply transfer between states. The important mechanic is not rotation alone, but center-origin rotation plus sand fill handoff inside a stable box.
Production issues usually come from the wrong pivot or from animating layout-sized sand. Keep transform-origin at center, reserve the loader footprint, animate clipped transform layers rather than height, and expose a single polite status message so the loop stays visual instead of becoming repeated assistive-tech noise.