webdevpuneet.com

Skeleton Loader — Free HTML CSS Shimmer Snippet

Skeleton Loader · Loaders · Plain HTML & CSS · Live preview

CategoryLoaders

Copy & paste

Source Code

<div class="cards">
  <div class="card">
    <div class="skel avatar"></div>
    <div class="skel line w60"></div>
    <div class="skel line w40"></div>
    <div class="skel block"></div>
    <div class="skel line w80"></div>
    <div class="skel line w50"></div>
  </div>
  <div class="card">
    <div class="skel avatar"></div>
    <div class="skel line w70"></div>
    <div class="skel line w45"></div>
    <div class="skel block"></div>
    <div class="skel line w90"></div>
    <div class="skel line w35"></div>
  </div>
</div>

Extend with AI

Take This Snippet Further With AI

The AI prompt for this one is for Patreon supporters ($3 a month, 7 days free), along with a site with no ads. Supporters enter the passcode once and it is remembered in this browser.

· Become a supporter

What's included

Features

CSS shimmer: linear-gradient with background-size: 200% and background-position keyframe
GPU compositor-thread animation — no layout or paint triggered, safe for many elements
.avatar utility: 44×44px circle for profile image placeholders
.block utility: 80px tall rectangle for image or chart area placeholders
.line utility: 10px tall strip for text line placeholders
Width utilities .w35 to .w90 for varied text line length realism
Two full skeleton cards shown simultaneously to demonstrate the layout
No JavaScript required — pure CSS animation
Export as HTML file, React JSX, or React + Tailwind CSS
Live split-pane editor — preview updates as you type

About this UI Snippet

Skeleton Loader — CSS Shimmer with background-size and Composable Shape Utilities

Screenshot of the Skeleton Loader snippet rendered live

A skeleton loader is a content placeholder that shows the approximate shape and layout of content while it loads. Instead of a generic spinner or loading dots in the centre of the screen, the user sees the card structure, text line positions, and image areas — the layout they are about to receive. Facebook, LinkedIn, and YouTube all use skeleton screens for exactly this reason: users orient themselves to the incoming layout rather than staring at an indeterminate wait.

How the CSS shimmer animation works

Each skeleton element has a background: linear-gradient(90deg, #e2e8f0 25%, #f1f5f9 50%, #e2e8f0 75%). This is a horizontal gradient that starts grey, brightens to near-white in the middle, then returns to grey. The key property is background-size: 200% 100% — the gradient is twice as wide as the element, so only half of it is visible at any time.

The @keyframes shimmer animation shifts background-position from 200% 0 (gradient starting off the right edge) to -200% 0 (gradient finishing off the left edge). As the animation plays, the bright middle section sweeps from right to left, creating the light-catching shimmer effect.

Why this is GPU-accelerated

Animating background-position (unlike animating width or opacity) runs on the browser's compositor thread without triggering layout recalculations or paint operations. This makes it safe to animate dozens of skeleton elements simultaneously with no performance impact.

The shape utility classes

The snippet uses composable utility classes applied alongside .skel: .avatar creates a 44×44px circle (for profile images), .block creates an 80px-tall rectangle (for image thumbnails or chart areas), and .line creates a 10px-tall strip (for text lines). Width utilities .w35 through .w90 set percentage widths so text line lengths vary naturally.

Compose them to mirror any content layout: avatar + two lines (profile header), block + three lines (article card), or three lines of varying widths (text paragraph).

Dark mode adaptation

Change #e2e8f0 (the base grey) to #1e293b and #f1f5f9 (the highlight) to #334155. The shimmer remains visible because the highlight is still lighter than the base, just at a lower overall brightness.

Hiding the skeleton on load

When your API call resolves, hide the skeleton container (skeleton.style.display = 'none') and show the real content container. For React, use a loading state: render the skeleton when isLoading === true and the real content when false.

Step by step

How to Use

  1. 1
    View the shimmer in the previewThe two skeleton cards render with the shimmer sweeping left to right continuously. Each placeholder matches the shape of a real content card.
  2. 2
    Match your content layoutIn the HTML panel, rearrange the .skel elements to match your real content. Use .avatar for circular images, .block for image areas, .line + width classes for text.
  3. 3
    Adjust shimmer speedIn the CSS panel, find animation: shimmer 1.4s infinite and change 1.4s. Faster (1s) feels more active; slower (2s) feels more subtle.
  4. 4
    Adapt for dark modeChange #e2e8f0 (base) to #1e293b and #f1f5f9 (highlight) to #334155 in the CSS panel for a dark theme skeleton.
  5. 5
    Connect to real contentWrap the skeleton in a container. When your API call resolves, hide the skeleton container and show the real content container.
  6. 6
    Export in your formatClick "HTML" for a standalone file, "JSX" for a React component, or "Tailwind" for a React + Tailwind version.

Real-world uses

Common Use Cases

Social media and content feeds
Show skeleton cards while fetching posts, comments, or notification lists. Users see the card layout immediately and perceive the wait as shorter.
E-commerce product and search grids
Display skeleton product cards on category pages and search results while the listing loads. Matches the grid layout the user will see.
Dashboard widgets and analytics
Use .block skeletons as placeholders for charts and .line skeletons for metric values that load after the initial render — or drop in the ready-made skeleton dashboard layout.
Learn background-size shimmer technique
Change the gradient colours and background-size value in the CSS panel to understand how the oversized gradient and position animation create the sweep.
Mobile app list views
Skeleton loaders feel native on mobile. Use the avatar + two-line pattern for a contacts list or the block + three-line pattern for a news feed.
Drop into any async data component
Use the skeleton HTML as the initial render state. Swap it for real content when the fetch resolves — no library needed, just toggle display or a conditional render.
Related: Video Buffering Overlay
See the Video Buffering Overlay for a related loaders pattern worth pairing with this one.

Got questions?

Frequently Asked Questions

Each skeleton element has a linear-gradient background that is 200% wide (background-size: 200% 100%). A keyframe shifts background-position from 200% 0 to -200% 0, sliding the lighter highlight from right to left. The bright middle section of the gradient sweeps across the element, creating the shimmer effect.

Animating background-position runs on the browser GPU compositor thread without triggering layout recalculations or paint. This is unlike animating width or height, which cause reflow. Many skeleton elements can animate simultaneously without impacting frame rate.

Combine .skel with .avatar (circle), .block (tall rectangle), or .line (thin strip). Add width classes (.w60, .w80, etc.) to vary text line lengths. Arrange them in the same structure as your real content so the skeleton matches the loaded layout.

Change the gradient colours: #e2e8f0 (base) to a dark surface like #1e293b and #f1f5f9 (highlight) to a slightly lighter value like #334155. The highlight must be visibly different from the base for the shimmer to show.

Keep the skeleton container and the real content container as siblings. When your API call resolves, set skeletonEl.style.display = "none" and contentEl.style.display = "block". In React, use a loading boolean: {isLoading ? <Skeleton /> : <Content data={data} />}.

Yes. Click "JSX" to download a React component. Create a Skeleton component that renders the placeholder shapes. Use it in your data-fetching components: render Skeleton while the fetch is in progress and replace with the real component when data arrives.