Skip to content
IzzyBlazor 0.1.0-alpha.17

Enter all results ↑ ↓ move Esc close

Skeleton

Stands in for content still loading.

A static page with IzzyBlazor's script. No circuit.

A shimmering placeholder in the shape of content that's still loading: lines of text, a block (an image, a card) or a circle (an avatar).

Usage

razor
<Skeleton Lines="3" />
<Skeleton Circle Width="Length.Rem(3)" />
<Skeleton Height="Length.Rem(10)" />   @* a block, such as an image or a card *@
<Skeleton Loaded="_order is not null" Lines="2">@_order.Summary</Skeleton>

Lines, blocks and circles

Use Lines for text, Height for a block such as an image, and Circle for an avatar.

Preview

Code

Shapes.razor
<Card Grow MaxWidth="22.Rem">
    <Stack Gap="4">
        <Row Gap="3" Align="Align.Center">
            <Skeleton Circle />
            <Skeleton Lines="2" Grow />
        </Row>
        <Skeleton Height="8.Rem" />
        <Skeleton Lines="3" />
    </Stack>
</Card>

Swapping in content

Use Loaded to show the real content in place of the placeholder once it arrives; a placeholder as tall as what it stands for keeps the page still.

Always Live

Preview

Order #1042

Customer
Items
Total

Code

Loaded.razor
@* The labels are known up front: only the values wait, each a line as tall as its text, so the
   card keeps its size when they arrive. *@
<Card Title="Order #1042" Grow MaxWidth="22.Rem">
    <DescriptionList Size="ControlSize.Sm">
        <DescriptionItem Term="Customer"><Skeleton Loaded="_order is not null" Width="8.Rem">@_order?.Customer</Skeleton></DescriptionItem>
        <DescriptionItem Term="Items"><Skeleton Loaded="_order is not null" Width="4.Rem">@_order?.Items</Skeleton></DescriptionItem>
        <DescriptionItem Term="Total"><Skeleton Loaded="_order is not null" Width="5.Rem">@_order?.Total</Skeleton></DescriptionItem>
    </DescriptionList>
    <CardFooter>
        <Button OnClick="LoadAsync" Variant="ButtonVariant.Outline" Accent="Accent.Neutral" Size="ControlSize.Sm" StartIcon="Lucide.RefreshCw">Reload</Button>
    </CardFooter>
</Card>

@code {
    private Order? _order;

    protected override Task OnAfterRenderAsync(bool firstRender) => firstRender ? LoadAsync() : Task.CompletedTask;

    private async Task LoadAsync()
    {
        _order = null;
        StateHasChanged();
        await Task.Delay(1500);
        _order = new("Grace Hopper", "3 items", "$128.00");
        StateHasChanged();
    }

    private sealed record Order(string Customer, string Items, string Total);
}

Mode support

What works in each mode, Skeleton
FeatureOffStaticLive
EverythingYesYesYes

Off: JavaScript disabled. Static: a static SSR page with IzzyBlazor's script. Live: an interactive page (Server, WebAssembly or Auto).

Accessibility

  • The placeholder has aria-hidden="true", so screen readers skip it.
  • Nothing is announced while it loads or when Loaded swaps in the content: announce the loading with a Spinner or the region's aria-busy.
  • With reduced motion the shimmer slows down.

Parameters

Skeleton parameters
PropTypeDefault
LinesLines of text to stand in for.int1
CircleA circle, such as an avatar.boolfalse
LoadedWhen true, shows ChildContent in place of the placeholder.boolfalse
ChildContentThe real content, shown once Loaded.RenderFragment?

See also

  • Spinner: a loading ring sized like an icon.
  • Progress: a progress bar, determinate or not.
  • EmptyState: what to show when there's nothing yet.