skeletonloader
Reactive icon

SkeletonLoader

Stable version 1.0.0 (Compatible with OutSystems 11)
Uploaded
 on 24 Jun (16 hours ago)
 by 
0.0
 (0 ratings)
skeletonloader

SkeletonLoader

Documentation
1.0.0

Skeleton Loader

A lightweight Reactive Web UI block that displays animated placeholder shapes (the "shimmer" effect) while your screen or data is loading — instead of a blank area or a spinner.

Platform: OutSystems 11 (O11) · Type: Reactive Web · Curation target: Community / Trusted


1. Overview

Skeleton Loader gives your users a sense that content is on its way. Rather than showing an empty screen or a generic spinner while data loads, you show grey placeholder shapes that mimic the layout of the real content, with a soft animated shine sweeping across them.

It is built entirely with CSS and a small amount of client-side logic — no integrations, no external services, no configuration required to get started. Drop the block on a screen, bind one boolean, and you have a working loading state.

Key features

  • Five ready-made shape types: Text, List, Table, Card, Avatar.
  • Configurable number of placeholder rows.
  • Optional width/height overrides per instance.
  • Built-in accessibility: respects the user's "reduce motion" system setting.
  • Pure CSS animation — lightweight and performant.
  • Collision-safe CSS (all classes are prefixed with osl-).

2. Compatibility

ItemRequirement
OutSystems versionOutSystems 11 (O11)
App typeReactive Web
DependenciesNone

Note: This component is designed for Reactive Web. It is not intended for Traditional Web or Mobile (though the CSS technique can be adapted).


3. Installation

  1. Open the Forge listing for Skeleton Loader and click Install (or download the .oap and install it via Service Center).
  2. Once installed, open Service Studio.
  3. In the module where you want to use it, go to the Manage Dependencies dialog.
  4. Select the Skeleton Loader module and check the Skeleton block (and the SkeletonType static entity).
  5. Click Apply and publish.

The Skeleton block is now available in your widget toolbox under the producer module.


4. Quick start

The minimum setup is three things: drop the block, put your real content inside it, and bind one boolean.

  1. Drag the Skeleton block onto your screen.
  2. Inside the block's content area, place the real content you want to show once loading finishes.
  3. Bind the block's IsLoading input to a boolean that is True while your data fetches and False once it arrives (for example, the Loading status of an Aggregate or Data Action).
Skeleton
  IsLoading = not MyDataAction.Done   // True while loading
  Type      = Entities.SkeletonType.Text
  Lines     = 3
  └── [your real content here]

While IsLoading is True, users see the shimmer placeholders. When it flips to False, your real content appears in their place.


5. Reference — the Skeleton block

Input parameters

ParameterTypeDefaultDescription
IsLoadingBooleanTrueWhen True, shows the placeholder shapes. When False, shows your real content.
TypeSkeletonType IdentifierTextWhich placeholder layout to display. See section 6.
LinesInteger3Number of placeholder rows to render (applies to Text, List, and Table types).
WidthText(empty)Optional CSS width override, e.g. "200px" or "50%". Leave empty to use defaults.
HeightText(empty)Optional CSS height override, e.g. "40px". Leave empty to use defaults.

Content placeholder

The block exposes a single content area (Content) where you place the real UI that should appear once loading completes. You only ever fill this once — it is not per-type.


6. Skeleton types

The Type input accepts values from the SkeletonType static entity:

TypeBest forWhat it renders
TextParagraphs, descriptionsStacked thin lines; the last line is shorter for a natural look.
ListSimple item listsStacked row-height bars.
TableTabular dataTaller, full-width row bars.
CardCards, tiles, imagesA single large rounded block.
AvatarProfiles, comments, contactsA circle plus two short text lines beside it.

Lines controls how many rows render for Text, List, and Table. It has no effect on Card or Avatar, which are single fixed layouts.


7. CSS classes (for customization)

All placeholder shapes use the base class osl-skeleton (which carries the shimmer animation) plus one shape class. If you want to restyle the component in your own app, override these classes in your app theme.

ClassPurpose
osl-skeletonBase class — the grey surface and shimmer animation. Always present.
osl-textThin text-line shape.
osl-list-rowList row shape (slightly taller than text).
osl-table-rowTable row shape.
osl-cardLarge card/block shape.
osl-avatarCircular avatar shape.

Each shape always combines two classes, e.g. osl-skeleton osl-text.


8. Customizing the look

Because the styles are plain CSS classes, you can override them from your consuming app's theme. Common tweaks:

Change the placeholder colour — override the base class:

.osl-skeleton {
  background: linear-gradient(90deg, #d4d4d8 25%, #e4e4e7 50%, #d4d4d8 75%);
  background-size: 200% 100%;
}

Slow down or speed up the shimmer — override the animation duration:

.osl-skeleton { animation-duration: 2.2s; }

Adjust a single instance's size — use the Width / Height inputs instead of CSS (no stylesheet edits needed).


9. Accessibility

The component respects the operating-system "reduce motion" preference. When a user has enabled reduced motion, the shimmer animation is disabled and the placeholders show as static grey shapes — still a valid, non-distracting loading indicator. No configuration is required for this; it works automatically.


10. How it works (brief)

There are two ideas behind the component:

The shimmer is a CSS trick. Each placeholder has a wide gradient background (twice the element width) with a bright band in the middle. A keyframe animation slides the gradient's position back and forth, so the bright band sweeps across a stationary element. This is cheap for the browser because only the background position moves.

The repeating rows (for Text, List, and Table) come from a small client-side list. On initialize, the block builds a list containing Lines items, and a List widget renders one placeholder row per item. The item values are never read — only the count matters, since every row is identical.


11. Troubleshooting / FAQ

The placeholders show but never disappear.Your IsLoading binding is staying True. Make sure it is tied to the loading status of your data source and flips to False when the data arrives.

The real content never shows.Confirm you placed your content inside the block's content area, and that IsLoading reaches False.

No shimmer animation, just static grey.This is expected if the user (or your test machine) has "reduce motion" enabled in OS settings. It is the accessibility behaviour, not a bug.

The number of lines doesn't change.Lines only applies to Text, List, and Table types. Card and Avatar are fixed layouts.

Styles look wrong / classes clash with my app.All classes are prefixed osl-. If you have your own classes with the same names, rename yours or scope the override.


12. Best practices

  • Match the Type to the real content's shape (use Card where a card will load, Text where a paragraph will load). The closer the placeholder mirrors the final layout, the smoother the transition feels.
  • Keep Lines close to the expected real row count so the layout doesn't jump when content loads.
  • Bind IsLoading to a real data-loading signal rather than a manual timer.

13. Support

For questions or issues, use the component's Support tab on its Forge listing. When reporting a problem, include your OutSystems version and a short description of how you configured the block (Type, Lines, and how IsLoading is bound).


14. Version history

VersionNotes
1.0.0Initial release. Text, List, Table, Card, and Avatar types; configurable line count; width/height overrides; reduced-motion support.

15. License

Published on the OutSystems Forge as open, reusable code. You are free to use and adapt it in your OutSystems projects.