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.