Skeleton
Frontbx's skeleton component lets you quickly display a placeholder preview of your content before the data gets loaded to reduce load-time and improve user experience on Pjax or Ajax requests.
Markup
Skeletons are simple to create, simply create an element with the .skeleton
class inside a component.
Note that Skeletons by default with fill all available vertical and horizontal space inside their container. If you're placing a skeleton inside an empty column or a container without a height you'll need to either specify a height on the container or on the skeleton itself.
The example below shows the markup for a skeleton using a simple card:
<div class="card">
<div class="card-header">
<div class="card-header-left">
<div class="skeleton skeleton-circle skeleton-wave" style="width: 40px; height: 40px;"></div>
</div>
<div class="card-header-content">
<div class="skeleton-text-block skeleton-lines">
<div class="skeleton" style="width: 71%;"></div>
<div class="skeleton" style="width: 81%;"></div>
</div>
</div>
</div>
<div class="card-media">
<div class="skeleton skeleton-block skeleton-wave" style="width: 100%; height: auto; aspect-ratio: 16 / 9;"></div>
</div>
<div class="card-block">
<div class="skeleton skeleton-h5"></div>
<div class="skeleton-text-block skeleton-lines">
<div class="skeleton" style="width: 81%;"></div>
<div class="skeleton" style="width: 84%;"></div>
<div class="skeleton" style="width: 91%;"></div>
</div>
</div>
</div>
Base Variants
Skeletons come in a few different base variants .skeleton-wave
, .skeleton-text
, .skeleton-rounded
, .skeleton-btn
, .skeleton-input
, .skeleton-circle
and via modifier classes.
The table below outlines their core styles
Class | Behavior |
---|---|
.skeleton-wave |
Sets skeleton animation to a wave effect. Good for images |
.skeleton-text |
Sets skeleton to height of body copy with matching margins with addition of rounded corners |
.skeleton-rounded |
Sets rounded corners on a skeleton |
.skeleton-btn |
Creates a rectangular fixed height and width skeleton to match Frontbx button sizing |
.skeleton-input |
Creates a rectangular fixed height skeleton to match Frontbx input sizing |
.skeleton-circle |
Sets skeleton to a circle. Width and height can adjusted via modifier sizes or overridden manually |
<div class="skeleton skeleton-text"></div>
<div class="skeleton skeleton-circle"></div>
<div class="skeleton skeleton-wave"></div>
<div class="skeleton skeleton-rounded"></div>
<div class="skeleton skeleton-input"></div>
<div class="skeleton skeleton-btn"></div>
.skeleton-circle
comes in three modifier sizes .circle-sm
, .circle-md
and .circle-lg
<div class="skeleton skeleton-circle circle-sm"></div>
<div class="skeleton skeleton-circle circle-md"></div>
<div class="skeleton skeleton-circle circle-lg"></div>
Text
To display text and the .skeleton-text
modifier class. The sizing, height and line height will match Frontbx's typography configurations:
Lorem ipsum dolore excepteur culpa sit.
Lorem ipsum velit amet officia minim fugiat.
Cillum laboris do est.
<div class="skeleton skeleton-text"></div>
<div class="skeleton skeleton-text"></div>
<div class="skeleton skeleton-text"></div>
To display text headings add the appropriate heading .skeleton-h[num]
modifier class. The sizing, height and line height will match Frontbx's typography configurations:
Heading 1
Heading 2
Heading 3
Heading 4
Heading 5
Heading 6
<div class="skeleton skeleton-h1"></div>
<div class="skeleton skeleton-h2"></div>
<div class="skeleton skeleton-h3"></div>
<div class="skeleton skeleton-h4"></div>
<div class="skeleton skeleton-h5"></div>
<div class="skeleton skeleton-h6"></div>
Text Blocks
For multi-line text blocks, wrap skeletons in a .skeleton-text-block
element.
Aliquip veniam eu enim quis sit nisi enim exercitation ad irure sunt ut pariatur, cillum reprehenderit do duis voluptate proident dolor sint duis. Id commodo cupidatat minim labore elit officia eu officia eu velit sunt veniam. Quis aute minim dolore voluptate nisi ut aliquip et exercitation commodo nisi enim sunt labore et nulla enim in minim consequat ea velit dolore reprehenderit aute anim voluptate consectetur magna enim consectetur fugiat in occaecat magna dolor culpa elit.
<div class="skeleton-text-block">
<div class="skeleton"></div>
<div class="skeleton"></div>
...
</div>
For multi-line heading use the same .skeleton-text-block
wrapper with the appropriate heading modifier .skeleton-text-block-h[num]
:
Lorem ipsum voluptate eiusmod.
<div class="skeleton-text-block skeleton-text-block-h1">
<div class="skeleton"></div>
<div class="skeleton"></div>
</div>
Lorem ipsum voluptate eiusmod.
<div class="skeleton-text-block skeleton-text-block-h2">
<div class="skeleton"></div>
<div class="skeleton"></div>
</div>
Lorem ipsum voluptate eiusmod velit.
<div class="skeleton-text-block skeleton-text-block-h3">
<div class="skeleton"></div>
<div class="skeleton"></div>
</div>
Lorem ipsum voluptate eiusmod velit excepteur quis ullamco.
<div class="skeleton-text-block skeleton-text-block-h4">
<div class="skeleton"></div>
<div class="skeleton"></div>
</div>
Lorem ipsum voluptate eiusmod velit excepteur quis ullamco.
<div class="skeleton-text-block skeleton-text-block-h5">
<div class="skeleton"></div>
<div class="skeleton"></div>
</div>
Eu cupidatat cupidatat ut consequat non cupidatat qui irure magna sunt ullamco eu non consectetur.
<div class="skeleton-text-block skeleton-text-block-h6">
<div class="skeleton"></div>
<div class="skeleton"></div>
</div>
To align skeleton text to the right, add the text-right
modifier to the wrapping element
In culpa voluptate laboris adipisicing.
In sed do incididunt labore magna elit ut consectetur do laborum ullamco do adipisicing mollit occaecat ad.
Enim veniam voluptate sunt non.
Incididunt amet nostrud in dolor aliquip in officia do ut duis incididunt ex ut.
<div class="skeleton-text-block skeleton-text-block-h3 text-right">
<div class="skeleton"></div>
</div>
<div class="skeleton-text-block text-right">
<div class="skeleton"></div>
</div>
<div class="skeleton-text-block skeleton-text-block-h4 text-right">
<div class="skeleton"></div>
</div>
<div class="skeleton-text-block text-right">
<div class="skeleton"></div>
</div>
Variant Examples
Try the example below create a few skeletons
JavaScript Utility
Frontbx comes with a handy JavaScript utility component for creating skeletons on the fly. You can create a skeleton by calling Skeleton
via the container.
Usage
const skeleton = frontbx.Skeleton(DOMElement, options);
The component will build the skeleton(s) with the supplied options and append them to the the DOMElement
.
Once you have created a Skeleton
instance, you can destroy it via the destroy
method. The skeleton(s) will be removed from the DOMElement
wrapper.
skeleton.destroy();
If you want to fade out skeletons before destroying use the fade_out
method. An optional callback can be supplied once the animation completes:
skeleton.fade_out(callback);
If you only want the skeleton(s) to fade out and want to destroy them manually, add a second argument as false
:
skeleton.fade_out(callback, false);
Options
The table below outlines the available options:
Option | Type | Default | Values |
---|---|---|---|
count |
integer |
1 |
Number of skeletons to generate. |
lines |
integer |
1 |
Optional value number of lines for Text Block variants. |
variant |
string |
block |
block text btn input circle wave rounded h1 h2 h3 h4 h5 h6 text-block block-h1 block-h2 block-h3 block-h4 block-h5 block-h6 |
width |
string |
null |
Any CSS width value |
height |
string |
null |
Any CSS height value |
aspectratio |
string |
null |
If provided will make skeleton width responsive while retaining aspect ratio. Value should be provided as w/h e.g 16/9 . |
Multi-variant values should be supplied as a single string separated by spaces. e.g for a wave block skeleton with rounded corners you would supply block wave rounded
as the variant
value.
const options = {
count: 5,
variant: 'block wave rounded',
width: '100%',
height: '60px'
};
const skeleton = frontbx.Skeleton(DOMElement, options);
When creating a multi-line text-block variant (text-block
block-h1
block-h2
block-h3
block-h4
block-h5
block-h6
), any other options apart from count
or lines
will be ignored.
There are no modifier options for these skeletons. Additionally, the JS component will set a random width on each skeleton to give a natural text paragraph look.
const options = {
lines: 3,
variant: 'text-block',
};
const skeleton = frontbx.Skeleton(DOMElement, options);
You can also provide options as an array to add multiple skeletons to single container element:
const options = [
{ lines: 2, variant: 'h3-block' },
{ lines: 6, variant: 'text-block' },
];
const skeleton = frontbx.Skeleton(DOMElement, options);
Or if you need more control to a layout you can provide an optional child selector
key for each variant-set. The skeleton will get inserted into the the selector element rather than the parent wrapper element.
const options = [
{ selector: '.js-heading', lines: 2, variant: 'h3-block'},
{ selector: '.js-text', lines: 6, variant: 'text-block' },
];
const skeleton = frontbx.Skeleton(DOMElement, options);
Loading Content
Once you have reference to a Skeleton
instance, you can gracefully load your own content in via the load
method.
The method accepts both html as a string
or an HTMLDomElement
node with an optional callback when the animation completes.
let content = '<div>...</div>';
const callback = () => console.log('Complete!');
skeleton.load(content, callback);
When calling load
on a multi-instance Skeleton, provide an object with the selector as key to replace the content:
let content =
{
'.title' : '<div>...</div>',
'.text' : '<p>...</p>',
'.image' : document.createElement('IMG'),
};
skeleton.load(content);
The example below shows swapping out the contents of card component. Click the Load content
button to try it out.
const [find] = frontbx.import(['find']).from('_');
const cardWrapper = find('.js-skeleton-loader-card');
const options =
{
'.js-card-header-left' : '<div class="avatar"><img ... /></div>',
'.js-card-header-content' : '<div class="text-bold">...</div>',
'.js-card-media' : '<img ... />',
'.js-card-title' : '<h5>...</h5>',
'.js-card-text' : '<p>...</p>',
};
frontbx.Skeleton(cardWrapper).load(options);
CSS Customization
Skeleton uses local CSS variables on all .skeleton
for enhanced component customization and styling. The base values are used by the UI to create all the sizing. Values for the CSS variables are set via Sass, so pre-compilation customization is still supported too.
Default values are set in the scss/_config.scss
file in Frontbx's source.
scss/_config.scss
$skeleton-bg-1: rgba(0, 0, 0, 0.2) !default;
$skeleton-bg-2: rgba(0, 0, 0, 0.4) !default;
$skeleton-text-radius: var(--fbx-border-radius) !default;
scss/components/_skeleton.scss
.skeleton
{
--fbx-skeleton-bg-1: rgba(0, 0, 0, 0.2);
--fbx-skeleton-bg-2: rgba(0, 0, 0, 0.4);
--fbx-bg-animation: 1s ease-in-out infinite normal none running skeleton-pulse;
--fbx-skeleton-width: 100%;
--fbx-skeleton-height: 100%;
--fbx-skeleton-radius: 0;
--fbx-skeleton-margin: 0;
--fbx-skeleton-display: block;
}
The example below shows customization using CSS Variables:
.skeleton
{
--fbx-skeleton-bg-1: var(--fbx-theme-primary-300);
--fbx-skeleton-bg-2: var(--fbx-theme-primary-600);
}