Advertisement

Synchronized Pure CSS Skeleton Loader

| by Vladimir | 2 min read | code by Simey
A11y Ready Advanced

Tech & Dependencies

HTML CSS

Features

  • Global Synchronization
  • Viewport-aware speed
  • No-JS Math
  • Light/Dark Mode

Browser Support

Chrome 111+ Edge 111+ Safari 16.4+ Firefox 128+

Core

This Synchronized Pure CSS Skeleton Loader pushes the boundaries of modern CSS by creating a unified “shimmer” effect that sweeps across multiple disparate elements simultaneously. Unlike standard skeleton loaders that animate each block independently, this implementation ensures a single, globally aligned gradient flow using advanced CSS math and Houdini properties.

Core Technique

The brilliance of this snippet lies in its ability to synchronize animations across different containers without a single line of JavaScript. It achieves this through two primary techniques: Global Fixed Backgrounds and Viewport-aware Math Hacks.

1. The Synchronization Secret: background-attachment: fixed

The key to making the shimmer look like one continuous light beam passing over the entire UI is the use of background-attachment: fixed. Normally, a background moves with its element. By fixing it to the viewport, every .skeleton element on the page renders a specific “slice” of one giant, screen-wide gradient. Even if elements are nested in different grids or flexboxes, the light sweep remains perfectly aligned.

.skeleton {
    /* Fixed attachment ensures all elements share the same global coordinate space for the gradient */
    background-attachment: fixed;
    background-image: linear-gradient(
        var(--skele-angle),
        hsl(from var(--skele-shine-color) h s l / 0) calc(var(--anim-pos)),
        hsl(from var(--skele-shine-color) h s l / 1) calc(var(--anim-pos) + var(--skele-size)),
        hsl(from var(--skele-shine-color) h s l / 0) calc(var(--anim-pos) + var(--skele-size) + var(--skele-leading-edge-blur))
    );
}

2. Advanced CSS Math: Type Casting

To calculate the animation speed dynamically based on the screen width, the author employs an ingenious hack using trigonometric functions (tan and atan2). This technique effectively “casts” a CSS length (like 100vw) into a unitless integer that can be used in complex calc() operations for animation timing - something previously impossible in pure CSS.

/* A hack to get viewport width as a unitless scalar */
--100vw: 100vw;
--int-width: calc(10000 * tan(atan2(var(--100vw), 10000px)));
/* Scale the speed: faster on large screens, slower on small ones */
--anim-time: calc(((var(--int-width) / var(--skele-distance)) * var(--skele-time)));

3. State Handling with @property

By registering custom properties via the CSS Properties and Values API (Houdini), the animation becomes much smoother. Defining --skele-pos as a <number> allows the browser to interpolate values accurately during the @keyframes cycle, enabling complex easing functions that standard string-based variables cannot handle.

Browser Support

This snippet relies on the latest CSS standards, including Houdini and math function interoperability. This code represents the future of CSS. While it works in all current “evergreen” browsers, it will not function in legacy environments (Internet Explorer or older pre-Houdini versions of Safari/Firefox).

Advertisement