On this page
Quick steps
Duplicate the finished screen
Start from the real, loaded version of the screen or card. Duplicate it (Cmd/Ctrl + D) so the skeleton inherits the exact layout, padding, and auto layout settings.
Replace text with grey bars
Swap each text layer for a rectangle about the height of the text's x-height to cap height, with a corner radius of 4 to 6 px. Vary the widths of multi-line paragraphs so the last line is shorter.
Replace images, avatars, and icons with blocks
Keep the image frames but remove the image fill and use a flat light grey. Avatars stay circles. Small icons can become 16 or 24 px squares, or be removed entirely.
Use one or two greys from variables
Pick a base grey for the blocks and a slightly lighter grey for the highlight. Store them as color variables so the skeleton follows light and dark mode.
Make it a component with a shimmer variant
Turn the skeleton into a component, then add a variant. In the second variant, place a soft white gradient band inside a clipped frame and move it from the left edge to the right edge.
Wire the loop with Smart Animate
In the Prototype tab, connect variant 1 to variant 2 and back with the After delay trigger, the Change to action, and Smart animate. Every instance of the component now loops in prototypes.
What is a skeleton loader?
A skeleton loader is a low-detail version of a screen that shows while real content loads. It uses grey shapes in the same positions as the text, images, and buttons that will appear, so the layout is visible before the data arrives. You see them in feeds, dashboards, product grids, and profile pages.
The point is layout stability. When content replaces the skeleton, nothing jumps, because every block already reserved its space. That is also why a skeleton has to match the real layout closely. A generic grey page that doesn't line up with the final screen causes the same shift you were trying to avoid.
Skeleton screen or spinner?
Use a skeleton when you know the shape of what is coming. A list of cards, an article, a table with a known column count, a user profile. Use a spinner or progress bar when you don't know the shape, when the wait is very short, or when the action is a single operation like saving a form.
- Skeleton: full-page or section loads, lists and grids, anything that takes longer than a moment and has a predictable structure.
- Spinner: button submits, small inline refreshes, uploads with no known layout.
- Progress bar: long operations where you can report a percentage, like file exports.
- Nothing: loads that finish before a person would notice. Flashing a skeleton for a split second is worse than showing no loader.
Keep skeletons simpler than the real UI. You don't need a bar for every tiny label or a block for every icon. Headline, two or three body lines, the image, and the primary button are usually enough to communicate the layout.
How to build a skeleton loader by hand in Figma
The steps above are the short version. Here is what matters at each stage when you do it manually.
Keep the auto layout from the real component
Start from a duplicate of the loaded design, not a blank frame. If your card uses auto layout with 16 px padding and 8 px gaps, the skeleton gets the same values for free. Delete text layers only after you've placed the replacement rectangle in the same auto layout slot, or the stack collapses.
Size the bars from the text, not the text box
A 16 px font with a 24 px line height should become a bar around 10 to 12 px tall, with the remaining space kept as gap. If you make the bars as tall as the text box, the skeleton looks heavy and blocky. Set the bars to Fill container width and shorten the last bar in a paragraph to around 60% so it reads as text.
Corner radius and color
Match the radius of the real elements for cards, images, and buttons. For text bars, 4 px is a common default, and fully rounded pills also work. For color, a base like #E5E7EB on white with a highlight around #F3F4F6 gives enough contrast without looking like disabled UI. Put both in variables and add a dark mode value, so the same component works on both themes.
Turn it into a component with variants
Select the skeleton and create a component, then add a second variant. Name the property something like State with values Base and Shimmer. If the loaded card is already a component, you can add the skeleton as a Loading variant of that same component set, which keeps it next to the real states in your library. For help naming and organizing variants, see how to set up component variants.
How to add a shimmer animation
The shimmer is a light band sliding across the grey blocks. In Figma there are two ways to build it.
Smart Animate between two variants
- In the
Basevariant, add a rectangle on top of the skeleton with a linear gradient fill: transparent, then white at around 60% opacity in the middle, then transparent again. Place it just outside the left edge. - Turn on Clip content on the variant frame so the band is hidden outside the card.
- In the
Shimmervariant, move the same band just past the right edge. The layer name must be identical in both variants, or Smart Animate won't match them. - Open the Prototype tab. Connect
BasetoShimmerwith the After delay trigger, the Change to action, and Smart animate at around 800 to 1,200 ms with an ease-in-out curve. - Connect
Shimmerback toBasethe same way, with a short duration. Now every instance loops in prototype mode.
Figma Motion keyframes
Figma Motion, announced at Config 2026 and in open beta, adds a timeline with keyframes to Figma Design. You can keyframe the band's position from left to right and set playback to loop. Because it is still in beta, check it on your plan before relying on it for team handoff, and keep the Smart Animate version as a fallback.
The faster way: convert a finished frame with a plugin
The slow part of the manual method is replacing layers one by one. On a dense dashboard that can be a hundred text layers. Skletons does that replacement for you. Select one or more frames, components, instances, or component sets and click Convert to Skeleton. The plugin puts a skeleton copy to the right of each original, with text as grey bars and images and shapes as grey rectangles. Layout and structure stay the same.
A few options decide what survives the conversion:
- Preserve Text keeps any text layer with
#in its name, likeTitle #. Useful for section headers or a button label you want to stay readable. - Preserve Images and Preserve Colors keep image fills and non-neutral brand colors instead of greying them out.
- Corner radius is a slider from Auto to 24 px. Auto keeps each element's original radius.
- Sketchy style and Squiggly text give a hand-drawn look, which suits wireframes more than production loaders.
- Lines, vectors, and gradients are always kept as they are.
Skletons makes the static skeleton. It doesn't add the shimmer, so use the Smart Animate steps above on the result. If you haven't used plugins before, here's how to install a Figma plugin. Other plugins in the Community, such as Skeleton Craft and Lazy Load, take a similar select-and-generate approach, so try more than one if your layouts are unusual.
Handing a skeleton loader off to developers
Engineers usually build skeletons from CSS, not from your exported shapes, so the useful handoff details are the numbers. Note the base and highlight colors (or the variable names), the bar heights and radius, the shimmer duration and easing, and which elements are left out. Put the skeleton variant next to the loaded state so the positions can be compared. For more on documenting that kind of detail, see the guide on writing Figma design specs.
Ranked listThe best Figma plugins for prototyping in 2026Frequently asked questions
Does Figma have a built-in skeleton loader?
No. Figma has no skeleton loader component or generator. You build one from rectangles and auto layout, copy one from a UI kit, or generate one from an existing frame with a plugin such as Skletons.
How do I make a skeleton loading animation in Figma?
Create a component with two variants, put a gradient band on the left in the first and on the right in the second, then connect them with an After delay trigger and Smart animate so they loop. In 2026 you can also use Figma Motion keyframes, which is in open beta.
What color should a skeleton loader be?
A light neutral grey on light backgrounds, such as #E5E7EB, with a slightly lighter highlight for the shimmer. On dark backgrounds, use a grey a few steps lighter than the surface. Store both as variables with light and dark modes.
Why doesn't my Smart Animate shimmer move?
Smart Animate matches layers by name and hierarchy. If the gradient band has a different name or sits in a different parent in each variant, Figma fades instead of moving it. Also check that the trigger is After delay and that Clip content is on.
Can a skeleton plugin keep some real text visible?
Skletons can. Turn on Preserve Text and add # to the name of any text layer you want to keep. Everything else becomes a grey bar.
More in Components & variants
- How to Generate All Component Variants in FigmaFigma shows only the variants you draw. Here's how to lay out every combination of variant, boolean and nested props as a matrix, by hand or with Instancer.
- How to Add Properties to a Figma ComponentAdd boolean, text, instance swap, variant and slot properties to a Figma component, link them to layers, and fix 'not used within component' warnings.
- How to Detach an Instance in Figma (and Remove a Component)Detach a Figma instance with ⌥⌘B or Ctrl+Alt+B. Why Detach is missing, how to detach a nested instance, and how to turn a main component back into a frame.
- How to Create a Component in FigmaCreate a Figma component with ⌥⌘K or Ctrl+Alt+K, the Create component button or a right-click. Plus bulk creation, instances and what the purple icon means.
- Why Are My Nested Components Not Working in Figma?Expose nested instance properties in Figma, fix 'components can't contain instances of themselves' and the swapped-with-parent error, and see what can't change.
- How to Swap an Instance in FigmaSwap a Figma instance from the Instance menu, with Quick insert (Shift+I) or by Alt-dragging a component onto it. Plus go to main, reset and restore shortcuts.
- How to Add a Slot to a Figma ComponentAdd a slot to a Figma component with Convert to slot (⌘⇧S or Ctrl+Shift+S) or Wrap in new slot. Settings, limits, and when to use slots vs instance swap.
- How to make a GIF in FigmaMake a GIF in Figma from frames with a plugin, export a Figma Motion animation as GIF, or record a prototype. Steps, loop and timing settings, and trade-offs.
- How to Add a Hover Effect in FigmaMake Default and Hover variants, connect them with While hovering, Change to and Smart animate. Plus why Figma hover states stick or don't fire, and the fix.
- How to Make a Prototype in FigmaPress Shift+E, drag the + from a layer to a frame, and pick a trigger, action and animation. How to add overlays, flows and share a Figma prototype link.
- How to Export Figma Variables to JSON (and CSS, Tailwind or CSV)Export Figma variables to JSON natively, convert them to CSS or Tailwind with Style Dictionary, and move variables between files with Variable Master.
