material-skeleton

Shimmer placeholders for loading fragments — three primitives (text / circular / rectangular), composites are plain markup. Pairs with Unpoly up-placeholder.

primitives — lines="3" text block (em-based, inherits the type scale), circular avatar, rectangular media block

headline-sized context

card placeholder — composed from the primitives with utility classes, next to the card it stands in for

Acme Corp

Quarterly review meeting notes and the follow-up action items from the west-region account team.

list placeholder — a few avatar + two-line rows

table placeholder inside material-data-table[loading] — the button simulates an Unpoly fragment round-trip

OrderCustomerTotal
SO-1041Acme Corp$12,400.00
SO-1038Globex Ltd$3,180.50
SO-1036Wayne Ent.$300.00

RTL — the shimmer sweeps with the reading direction

prefers-reduced-motion: reduce swaps the sweep for a gentle opacity pulse (toggle it in OS settings / DevTools rendering emulation to see)

Sample usage (Django / Unpoly)
<!-- primitives; composites are plain markup -->
<material-skeleton lines="3"></material-skeleton>
<material-skeleton variant="circular"></material-skeleton>
<material-skeleton variant="rectangular" class="h-32"></material-skeleton>

<!-- Unpoly: show a placeholder while the fragment loads -->
<a href="{% url 'orders' %}" up-target=".order-list"
   up-placeholder="&lt;material-skeleton lines='6'&gt;&lt;/material-skeleton&gt;">
  Orders
</a>

<!-- or a reusable template -->
<template id="list-placeholder">
  <material-skeleton lines="6"></material-skeleton>
</template>
<a href="…" up-target=".order-list" up-placeholder="#list-placeholder">Orders</a>