The m3e-skeleton component provides a loading placeholder surface with flexible shape variants
and motion-based animations that communicate loading state while preserving layout stability. It mimics the
layout of content while it's still loading, ensuring a smooth user experience during data fetching or
rendering delays.
import "@m3e/web/skeleton";
This section outlines usage examples and configuration guidance for the components in this package.
Use the m3e-skeleton component to generate loading placeholders for any top-level slotted
elements. The component creates an overlay shape for each node, matching its geometry while preserving the
layout of the underlying content.
Use the loaded attribute to reveal loaded content.
<m3e-skeleton>
<m3e-card>
<m3e-heading slot="header" variant="display" size="small">Card Header</m3e-heading>
<div slot="content">Card Content</div>
<div slot="actions">
<m3e-button variant="filled">Action</m3e-button>
</div>
<div slot="footer">Card Footer</div>
</m3e-card>
</m3e-skeleton>
Use the shape attribute to define the geometry applied to all top level slotted content. Each
node receives a corresponding skeleton overlay that reflects the selected shape. The
circular option produces a circle based on the element size. The rounded option
applies the standard radius token used by most surfaces and controls. The square option renders
with no radius for a sharp edge appearance. The auto option reads the actual border radius of the
slotted element and mirrors it exactly, ensuring the skeleton aligns with cards, buttons, images, or any
custom component without additional configuration.
<m3e-skeleton shape="circular"> <div style="width: 100px; height: 100px"></div> </m3e-skeleton> <br /> <m3e-skeleton shape="rounded"> <div style="width: 100px; height: 100px"></div> </m3e-skeleton> <br /> <m3e-skeleton shape="square"> <div style="width: 100px; height: 100px"></div> </m3e-skeleton> <br /> <m3e-skeleton shape="auto"> <div style="width: 100px; height: 100px; border-radius: 16px"></div> </m3e-skeleton>
Use the animation attribute to control how the skeleton communicates loading progress. When
enabled, the component applies motion across all top level slotted content to indicate that data is being
fetched. The wave option renders a smooth directional sweep that suggests ongoing work. The
pulse option applies a rhythmic fade in and fade out effect that draws attention without strong
directional movement.
<m3e-skeleton shape="circular" animation="pulse"> <div style="width: 100px; height: 100px"></div> </m3e-skeleton> <!-- Additional skeletons omitted for brevity -->
The none option disables motion and displays a static placeholder for environments that prefer
reduced movement or for layouts that require a quiet loading state.
<m3e-skeleton shape="circular" animation="none"> <div style="width: 100px; height: 100px"></div> </m3e-skeleton> <!-- Additional skeletons omitted for brevity -->
A skeleton's color uses the lowest perceptual contrast that remains reliably visible, keeping the placeholder subtle and non-intrusive.
Skeletons are purely visual placeholders and should not expose any semantic role or announce themselves to
assistive technologies. The m3e-skeleton element remains neutral and should have no role, no
aria-label, no aria-live, and no aria-busy. Loading state should be communicated by applying
aria-busy="true" to a parenting container, ensuring screen readers understand that content is
loading without being interrupted by decorative placeholders.
The @m3e/web package uses
JavaScript Modules. To use it directly in a browser without a bundler, use a module script similar to the following.
<script type="module" src="/node_modules/@m3e/web/dist/skeleton.js"></script>
In addition, you must use an import map to include dependencies.
<script type="importmap">
{
"imports": {
"tslib": "https://cdn.jsdelivr.net/npm/tslib@2.8.1/+esm",
"lit": "https://cdn.jsdelivr.net/npm/lit@3.3.0/+esm",
"lit/": "https://cdn.jsdelivr.net/npm/lit@3.3.0/",
"lit-html": "https://cdn.jsdelivr.net/npm/lit-html@3.3.0/+esm",
"lit-html/directive.js": "https://cdn.jsdelivr.net/npm/lit-html@3.3.0/directive.js",
"@lit/reactive-element": "https://cdn.jsdelivr.net/npm/@lit/reactive-element@2.0.4/+esm",
"@lit/reactive-element/": "https://cdn.jsdelivr.net/npm/@lit/reactive-element@2.0.4/",
"@m3e/web/core": "/node_modules/@m3e/web/dist/core.js",
"@m3e/web/core/anchoring": "/node_modules/@m3e/web/dist/core-anchoring.js"
}
}
</script>
For production builds, use the minified files to ensure optimal load performance.
The @m3e/web package includes a
Custom Elements Manifest
(custom-elements.json), which documents the properties, attributes, slots, events and CSS custom
properties of each component.
You can explore the API below, or integrate the manifest into your own tooling.