Loading States Snippets — Free HTML CSS JS Skeleton & Loading State Examples

98 snippets tagged Loading States · Live preview · Exports to React, Vue, Angular & Tailwind

What's included

Features

Skeleton screens shaped like the content they are standing in for
Shimmer placeholders built from a single animated gradient
Determinate progress bars and rings with real percentage feedback
Upload progress with per-file state, cancel and retry
Staged loaders that name the current step during a long operation

About this tag

Loading States Snippets — 98 Free Skeleton & Loading State Examples

A loading state is a promise about how long a wait will be. Skeletons imply "nearly there and this is the shape", spinners imply "unknown but short", progress bars imply "measurable" — and choosing the wrong one is why some waits feel longer than they are.

These snippets cover all three plus the surrounding cases: shimmer placeholders matched to real content, determinate and indeterminate progress, upload indicators with cancel, staged multi-step loaders, and the empty and error states a load can end in.

Matching the loader's shape to the wait's shape

A skeleton implies the layout is already known and reserves the exact space the real content will occupy, which is why it suits predictable, structured loads like a list of cards or a profile page. A spinner implies no particular shape or duration and suits short, unpredictable waits — a button submission, a small inline fetch. Using a skeleton for a two-hundred-millisecond load, or a bare spinner for a five-second one, is a mismatch between the signal given and the wait actually experienced.

The shimmer, and why it costs almost nothing

A shimmer placeholder is one linear-gradient, wider than the element it sits inside, animated across it by moving background-position — a single composited property. Because the animation is one property on one background layer, a page full of shimmering skeleton blocks costs about the same as a single one, which is what makes it viable to use liberally across a loading layout.

Delay before showing, minimum duration once shown

A loader that appears immediately on every request flashes on and off for anything that resolves quickly, which reads as instability rather than responsiveness. Delaying its appearance by roughly 200 to 300 milliseconds absorbs the requests that finish before anyone would notice a loader at all, and once one has appeared, keeping it visible for a minimum duration prevents it from disappearing mid-render in a way that looks like a glitch.

Progress that is honest about what it knows

A determinate progress bar promises a real percentage and should only be shown when one is actually available — an upload with byte counts, a multi-step process with known step count. An indeterminate bar or spinner is the honest choice when no such number exists; faking a percentage that does not correspond to real progress erodes trust in every progress bar the product shows afterward.

Real-world uses

Common Use Cases

Initial page and dashboard loads
A skeleton keeps the layout stable, which removes the content jump a spinner leaves behind.
File uploads and long operations
Measurable progress with a cancel path is the difference between waiting and wondering.
Button and inline loading
A button that shows its own pending state prevents the double submit it would otherwise get.
Perceived performance work
Optimistic updates and staged messaging change how long a wait feels without changing how long it is.

Got questions?

Frequently Asked Questions

Skeleton when you know the shape of what is coming and the wait is more than about half a second — it reserves layout and reads as progress. Spinner for short, unpredictable waits or small inline actions. A skeleton for a two-hundred-millisecond load is just a flash of grey.

No — delay it by roughly 200 to 300 milliseconds. Most requests finish inside that window, and a loader that flashes on and off makes a fast interface feel unstable. Once shown, keep it visible for a minimum duration so it does not blink out mid-render.

One linear-gradient with a lighter band, sized wider than the element, animated across it by moving background-position. It is a single composited property, so a page full of shimmering placeholders still costs almost nothing.

No. Every snippet is plain HTML, CSS and vanilla JavaScript that runs in any page — a static file, a WordPress theme, a Rails view, anything. When you do want a framework version, the editor exports each snippet as a React component, a React + Tailwind component, a standalone Tailwind HTML file, a Vue 3 single-file component or an Angular standalone component.

Yes — copy, modify and ship them in personal or commercial work, with no attribution required and no licence to track.

Yes. Every snippet opens in a live editor with separate HTML, CSS and JS panels and a preview that updates as you type. Check it at mobile, tablet and desktop widths, then copy the code or export it in your framework of choice.