Skip to main content

Glimmer Skeleton

A loading placeholder with a soft light sweep driven by Motion instead of injected keyframes, so any number of blocks stay in sync and reduced motion hides the sheen. Six rounding presets compose into cards, avatars, and text lines; the demo cycles a feed card between skeleton and loaded states.

LoadingReactMotionTailwind CSSSolar Icons
CSSTailwind

Manual

Create a file and paste the following code into it.

glimmer-skeleton.tsx
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
"use client";

import { type HTMLAttributes } from "react";
import { motion } from "motion/react";

import { cn } from "@/lib/cn";

/* ------------------------------------------------------------------ */
/*  Types                                                              */
/* ------------------------------------------------------------------ */

export interface GlimmerSkeletonProps extends HTMLAttributes<HTMLDivElement> {
  /** Corner rounding of the block. [Optional, default: "md"] */
  rounded?: "none" | "sm" | "md" | "lg" | "xl" | "full";
  /** Set false to pause the sweep (e.g. offscreen lists). [Optional, default: true] */
  animate?: boolean;
}

const ROUNDED_CLASS: Record<NonNullable<GlimmerSkeletonProps["rounded"]>, string> = {
  none: "rounded-none",
  sm: "rounded-sm",
  md: "rounded-md",
  lg: "rounded-lg",
  xl: "rounded-xl",
  full: "rounded-full",
};

/* ------------------------------------------------------------------ */
/*  GlimmerSkeleton                                                    */
/* ------------------------------------------------------------------ */

/**
 * A loading placeholder block with a soft light sweep. The sweep is a
 * Motion-driven gradient pass, so any number of skeletons stay in sync
 * without injecting per-instance keyframes, and it hides itself under
 * prefers-reduced-motion.
 * @param {string} rounded - Corner rounding preset [Optional, default: "md"]
 * @param {boolean} animate - Whether the sweep runs [Optional, default: true]
 */
export function GlimmerSkeleton({
  className,
  rounded = "md",
  animate = true,
  ...props
}: GlimmerSkeletonProps) {
  return (
    <div
      role="status"
      aria-label="Loading"
      className={cn(
        "relative overflow-hidden bg-zinc-200/80 dark:bg-zinc-800/90",
        "[--sheen:rgba(255,255,255,0.65)] dark:[--sheen:rgba(255,255,255,0.07)]",
        ROUNDED_CLASS[rounded],
        className,
      )}
      {...props}
    >
      {animate && (
        <motion.span
          aria-hidden="true"
          className="pointer-events-none absolute inset-0 motion-reduce:hidden"
          style={{
            background:
              "linear-gradient(90deg, transparent 0%, var(--sheen) 50%, transparent 100%)",
          }}
          initial={{ x: "-100%" }}
          animate={{ x: "100%" }}
          transition={{ duration: 1.5, ease: "easeInOut", repeat: Infinity }}
        />
      )}
    </div>
  );
}

Update the import paths to match your project setup.

Similar components

Max

Chaotic Dots Loader

Pixel Wave Animation

Install via CLI

Resource details

PublishedJuly 16, 2026
CategoryLoading
ReactMotionTailwind CSSSolar Icons