Skeleton Screen Generator
Build layout-matched skeleton loaders — card, list, article, profile, table, media, comment, grid, or custom — with live shimmer, pulse, or wave animation. Export self-contained HTML + CSS, CSS, a React component, or Tailwind markup, with prefers-reduced-motion and ARIA baked in.
About this ToolHow it works, benefits & use casesTap to collapse
A good skeleton screen does not just flash grey boxes — it mirrors the shape of the content that is about to load, so the layout does not jump when real data arrives. This generator is built around that idea: instead of picking abstract shapes, you pick a layout template — card, list, article, profile header, table, media object, comment thread, image grid, or fully custom — and it produces a placeholder that matches. Choose a shimmer, pulse, or wave animation, set the base and highlight colors, and tune speed, corner radius, gap, and the number of repeated rows. The live preview renders the actual animated skeleton and includes a "show real content" toggle so you can compare the placeholder against a mock of the finished UI. Every export is accessibility-aware: the skeleton is marked aria-hidden, paired with a polite live region, and the emitted CSS honors prefers-reduced-motion by disabling the animation. Copy a self-contained HTML + CSS snippet, standalone CSS, a React component, or Tailwind utility markup.
How to Use
- 1Pick a layout template that matches the content you are loading — card, list, article, profile, table, media object, comment, grid, or custom.
- 2Choose an animation (shimmer, pulse, wave, or none) and set the shimmer direction, base color, and highlight color.
- 3Tune speed, corner radius, gap, and — for list, grid, table, and comment layouts — the number of repeated items.
- 4For the custom template, add lines and set each one's type (text, avatar, image, button, or rect) plus width and height.
- 5Toggle "show real content" to compare the skeleton against a mock of the finished layout, then pick an output format and copy, download, or share it.
Key Benefits
- Layout templates that match real content so the page does not reflow when data loads
- Shimmer, pulse, and wave animations rendered live before you export
- A "show real content" toggle to compare the placeholder against the finished UI
- prefers-reduced-motion guard and aria-hidden + polite live region built into every export
- Four output formats: self-contained HTML + CSS, CSS, a React component, and Tailwind markup
- Custom template with per-line type, width, and height for bespoke layouts
- Namespaced class and keyframe names so the CSS never clashes with your styles
Common Use Cases
- Adding a loading state to a feed, dashboard, or list that matches its real layout
- Showing a card or profile placeholder while async data is fetched
- Generating a reusable React skeleton component for a design system
- Producing Tailwind animate-pulse markup that drops into an existing project
- Prototyping perceived-performance improvements without building the real UI first
Copy, download, share, or pipe to another tool
<style>
.skeleton__b {
background-color: #e5e7eb;
background-image: linear-gradient(90deg, #e5e7eb 0%, #f3f4f6 50%, #e5e7eb 100%);
background-size: 200% 100%;
background-repeat: no-repeat;
animation: skeleton-shimmer 1.5s linear infinite;
}
@keyframes skeleton-shimmer {
0% { background-position: -100% 0; }
100% { background-position: 100% 0; }
}
.skeleton__b { display: block; }
.skeleton__sr {
position: absolute;
width: 1px;
height: 1px;
padding: 0;
margin: -1px;
overflow: hidden;
clip: rect(0, 0, 0, 0);
white-space: nowrap;
border: 0;
}
@media (prefers-reduced-motion: reduce) {
.skeleton__b { animation: none !important; background-image: none !important; }
}
</style>
<div class="skeleton" aria-hidden="true">
<div style="display:flex;flex-direction:column;gap:12px">
<div class="skeleton__b" style="width:100%;height:160px;border-radius:8px"></div>
<div class="skeleton__b" style="width:90%;height:14px;border-radius:6px"></div>
<div class="skeleton__b" style="width:100%;height:14px;border-radius:6px"></div>
<div class="skeleton__b" style="width:70%;height:14px;border-radius:6px"></div>
</div>
</div>
<span class="skeleton__sr" role="status" aria-live="polite">Loading...</span>Accessibility
- Mark the skeleton aria-hidden="true" and expose the loading state through a polite live region (role="status", aria-live="polite").
- Honor prefers-reduced-motion: the emitted CSS disables the animation and shows a static placeholder for users who request reduced motion.
- Match the skeleton's shape and spacing to the real content so the layout does not jump when content arrives.
- Keep the animation subtle and slow enough to avoid distraction; very fast shimmer can be uncomfortable.
Was this tool helpful?
Share Your Experience
Help others discover this tool!
Related tools
- CSS FormatterFormat and beautify CSS code
- Component Name GeneratorTurn a description into ranked, kind-aware component names with a file scaffold and a name validator (casing, collisions, clarity)
- Lorem Pixel GeneratorGenerate placeholder image URLs
- Spacing Scale CalculatorLinear, geometric, Fibonacci or modular spacing scales with a visual ruler preview and utility classes — export CSS, Tailwind v4, SCSS, JSON
- SVG to React ComponentConvert SVG to a clean TSX/JSX/React Native component — currentColor, prop spread, forwardRef, memo, live preview
- Tailwind Config GeneratorVisually build a Tailwind config - theme extend, colors, spacing, fonts, screens, plugins - and export it as a v3 JS config or a v4 @theme CSS block
A skeleton works best when it occupies the same space as the content it replaces, so the layout does not shift when real data arrives. Templates like card, list, profile, table, and grid reproduce the real structure — image areas, avatars, text lines, and repeated rows — instead of generic blocks, which makes the transition feel seamless.
Shimmer and wave both sweep a lighter highlight gradient across each block — shimmer uses linear timing for a steady sweep, wave uses ease-in-out for a softer one. Pulse instead fades the whole block's opacity up and down. "None" leaves a static placeholder. All three are pure CSS keyframes with no JavaScript.

