Skip to content

Skeleton

Show where content will appear while it loads, holding its space so the page around it moves less.

Loading…

Release notes

What changed this week.

<script setup lang="ts">import { ref } from 'vue'import { UiCard, UiRadioGroup, UiRadio } from 'grani' const card = ref('loading')</script> <template>  <!-- A card, a table and a drawer draw it themselves under `loading`. -->  <div class="flex w-full flex-col items-center gap-4">    <UiCard      title="Release notes"      description="What changed this week."      :loading="card === 'loading'"      class="w-full max-w-xs"    >      <p v-if="card === 'loaded'" class="text-sm text-fg-muted">        Invoices export to CSV, the period picker remembers the last range, and the search in a        list clears with Escape.      </p>    </UiCard>    <UiRadioGroup v-model="card" variant="segmented" aria-label="State of the card">      <UiRadio value="loading">Loading</UiRadio>      <UiRadio value="loaded">Loaded</UiRadio>    </UiRadioGroup>  </div></template>

Also called loading placeholder, shimmer, content placeholder.

Usage

<UiSkeleton />

With GraniResolver in the Vite config, a template needs no import: set it up once.

API

DecisionWhat it does
SizeSize and shape come from the classes the host passes (h-4 w-32, h-64 w-full, rounded-pill for an avatar); without them it has no size. A line of text is an inline-block h-3 align-middle inside a block of the text's size, which keeps the line's height. A page skeleton is several of these, mirroring the real layout.
DecorationIt is decoration, and its shimmer is the sign that the first load runs: under reduced motion it keeps shimmering, slower, since a still gray block reads as a broken page. The host's live region announces the loading state.
By handUiCard, UiTable, UiDataTable, UiCrudDrawer and UiChartCard (with its charts) draw it themselves under loading. Place it by hand only in blocks of your own, which bring their own role="status" and drop it when the data comes.

When to use another component

When you needTake
An action in flightSpinner
Work measured or of unknown lengthProgress
Nothing there or a failed loadNo data
Loading a card, a table, a drawer or a chart cardCard, Table, Crud drawer and Chart card draw it themselves under loading