ComponentsSkeleton
Feedback

Skeleton

A vertical-column shimmer that mirrors real reader metrics while content loads.

Design question

How should loading state look in a column-based vertical reader without layout shift?

Decision

The skeleton should mirror the actual column geometry · same column width, same approximate glyph density · so content lands where the ghosts were.

Column skeleton

The skeleton mirrors the real column geometry · same width, same cell height, same RTL column order · so text lands exactly where the ghosts were. It pulses (opacity) rather than sweeping a horizontal shimmer.

tsx
1function ColumnSkeleton({ columns = 3, cellHeight = 24, cellsPerColumn = 20 }) {
2 return (
3 <div style={{
4 display: "flex",
5 flexDirection: "row-reverse", // RTL column order
6 gap: 32,
7 padding: 24,
8 }}>

Guidance

Do
  • Match skeleton column width and cell height to actual rendered values
  • Use RTL column order in the skeleton · columns flow right-to-left
  • Vary glyph-level density slightly for visual realism
Don't
  • Use horizontal paragraph skeletons in a vertical reader
  • Animate skeleton with a horizontal shimmer · use pulse opacity instead
  • Show skeletons for less than 200ms · content loads too fast to need them

Accessibility

aria-busy='true' on the container. aria-label describing what's loading. Remove when content appears.

Open question

Should the skeleton shimmer animate top-to-bottom (following reading direction) or use a simple pulse? Does directionality in the loading animation matter?