Skeleton loader
A skeleton loader is a simplified preview of loading content.
Examples
Structure
- Shapes: Simple shapes represent different content types in a single skeleton loader.
Guidelines
When to use
- Use the skeleton loader when loading content and a loading spinner is not prominent enough.
- Use when there is more than a single content element loading at the same time that requires an indicator.
- Offer a simplified preview of loading content to help manage user expectations while decreasing perceived load time.
- Avatars, cards, charts, content blocks, lists, and tables are good candidates for a skeleton state.
When not to use
- Instantly loading content doesn't need a skeleton loader.
- For an inline action or feedback, like an alert, consider a spinner or no loading state instead.
- Dynamic content revealed upon user interaction shouldn't be replaced by a skeleton loader, as the content should already be loaded by the time the user is able to interact with it. For example, content within a toast message, dropdown menu, or modal.
- For background processes, a loading state tied to a specific component, or a piece of existing content, use a spinner instead.
- A skeleton loader shouldn’t be used in combination with a spinner, choose the one that fits the use case best.
Appearance
- Comprised of one or more basic, grayscale shapes that have a horizontally pulsing motion to indicate they are loading.
- Use rounded corners, even for rectangular shapes. Shapes follow the standard spacing guidelines.
- Each shape should represent content in a recognizable way. For example, a long rectangle for a line of text or a circle for an avatar.
Custom skeleton loaders
To create a new skeleton loader:
- Start by designing with the variants in the Pajamas UI Kit and use spacing that follows the geometric progression.
- Output an SVG of the skeleton loader.
- Use the
<gl-skeleton-loader>
component and customize the SVG properties.
Behavior
- Content immediately replaces each skeleton loader when it's available.
Accessibility
- When a change occurs in the UI, like a loading state, it's good practice to notify the user what's happening. However, since a skeleton loader should only be present for a short period of time, and during an expected loading period, it does not need to be a live region or communicate that the page is busy.
Reference
- The Skeleton Loading component has been deprecated in favor of the Skeleton Loader.
- Everything you need to know about skeleton screens, by Bill Chung.
- More Accessibile Skeletons, by Adrian Roselli.
Code reference
Skeleton loaders are to be used when pages or sections can be progressively populated with content, such as text and images, as they become available. Generally speaking the first batch of content will be the lightest to load and is followed by secondary and tertiary content batches. Each loading step will add in more detail to the page until no skeleton loaders are present anymore. Content should replace skeleton objects immediately when the data is available.
The skeleton loader component accepts shapes which in return will create a skeleton state with a
loading animation. Any skeleton state components should be created with
<gl-skeleton-loader></gl-skeleton-loader>
. If no shape is passed via the slot the default skeleton
will be used. See "Default" and "Default With Custom Props" examples.
.gl-animate-skeleton-loader
class
The Skeleton loaders can also be composed with a .gl-animate-skeleton-loader
CSS class. This CSS-based approach is easier to make responsive and match mocked elements.
Feel free to use this approach if it suits your use case and please leave your
feedback in this Feedback for css-based skeleton loading
indicator issue.
To improve developer experience and simplify matching Pajamas styles we're considering
several improvements in the future, including adding more CSS util classes for
this animation, or creating a dedicated component. Here is an example of how
you could replicate the default <gl-skeleton-loader />
behavior with the
CSS-based approach:
<div>
<div class="gl-animate-skeleton-loader gl-h-4 gl-rounded-default gl-my-3 !gl-max-w-20"></div>
<div class="gl-animate-skeleton-loader gl-h-4 gl-rounded-default gl-my-3 !gl-max-w-30"></div>
<div class="gl-animate-skeleton-loader gl-h-4 gl-rounded-default gl-my-3 !gl-max-w-26"></div>
</div>
USAGE NOTES: if you're using gl-max-w-xx
you'll need to add
important (e.g. !gl-max-w-20
). This is because .gl-animate-skeleton-loader
already
has a max-width
statement, and we need to override it. You can override it
only with lower numbers. Width rules (gl-w-xx
) don't need an override, you
can use them as-is. If you want to "synchronize" two elements next to each
other, try adding animation-delay
to offset elements.
More complex example (with different shapes and an animation delay for offset elements):
<div class="gl-display-flex gl-flex-direction-column gl-gap-2 gl-w-30">
<div class="gl-animate-skeleton-loader gl-h-8 gl-rounded-default gl-mb-4"></div>
<div class="gl-display-flex gl-flex-direction-row gl-gap-2">
<div class="gl-animate-skeleton-loader gl-h-8 gl-w-8 gl-rounded-full"></div>
<div class="gl-flex-grow-1" style="animation-delay: 100ms">
<div class="gl-animate-skeleton-loader gl-h-4 gl-rounded-default gl-my-2"></div>
<div class="gl-animate-skeleton-loader gl-h-4 gl-rounded-default gl-my-2"></div>
<div class="gl-animate-skeleton-loader gl-display-inline-block gl-h-4 gl-w-10 gl-rounded-default gl-my-2"></div>
<div
class="gl-animate-skeleton-loader gl-display-inline-block gl-h-4 gl-w-10 gl-rounded-default gl-my-2"
style="animation-delay: 250ms"></div>
</div>
</div>
</div>
Progressive Loading
Determine if progressive loading is available, if it is break apart the skeleton to load data as it becomes readily available. If progessive loading is not available, replace the entire skeleton when the data is available.
Under the hood
Skeleton Loader is a port of vue-content-loader.
Some changes have been made to the code to better suit our codebase, such as removing props and
refactoring into a SFC. Please take a look at their documentation and a useful UI tool
for seeing the code output for svg
shapes.
GlSkeletonLoader
Related
Last updated at: