Squelette

Un squelette tient la place du contenu pendant son chargement. Sur un site statique c’est plus rare que dans une application — le HTML est déjà là — mais c’est en général ce que devrait être le fallback d’un îlot, et ce qu’affiche une zone rendue côté client avant que ses données arrivent.

Les squelettes sont décoratifs : chacun est aria-hidden, pour qu’un lecteur d’écran ne se voie pas lire une liste de boîtes vides.

Formes

stack({ gap: 'md' },
  skeleton({ height: '2.5rem' }),
  skeleton({ variant: 'text', width: '70%' }),
  skeleton({ variant: 'circle', width: '3rem', height: '3rem' }),
)

Texte

lines rend l’équivalent d’un paragraphe, la dernière ligne courte pour que cela se lise comme de la prose et non comme un bloc.

stack({ gap: 'lg' },
  skeleton({ lines: 2 }),
  skeleton({ lines: 4 }),
)

À la forme de la vraie chose

Un squelette est le plus convaincant quand il épouse la mise en page qu’il remplace — même carte, mêmes rangées, mêmes tailles.

AL

Ada Lovelace

A poussé 3 commits
grid({ min: '14rem' },
  card(
    cardBody(
      stack({ gap: 'md' },
        stack({ direction: 'row', gap: 'sm', align: 'center' },
          skeleton({ variant: 'circle', width: '2.5rem', height: '2.5rem' }),
          stack({ gap: 'xs', style: 'flex: 1' },
            skeleton({ variant: 'text', width: '60%' }),
            skeleton({ variant: 'text', width: '40%' }),
          ),
        ),
        skeleton({ lines: 3 }),
      ),
    ),
  ),
  card(
    cardBody(
      stack({ direction: 'row', gap: 'sm', align: 'center' },
        avatar({ name: 'Ada Lovelace' }),
        stack({ gap: 'none' },
          text({ variant: 'small' }, 'Ada Lovelace'),
          text({ variant: 'caption', tone: 'muted' }, 'A poussé 3 commits'),
        ),
      ),
    ),
  ),
)

Comme repli d’un îlot

Un îlot serveur embarque son repli dans le HTML statique et y glisse le fragment rendu au moment de la requête. Un squelette de la même forme que le fragment évite que la page saute à son arrivée.

Commentaires

card(
  cardHeader({ title: 'Commentaires' }),
  cardBody(
    stack({ gap: 'md' },
      skeleton({ lines: 2 }),
      divider({ spacing: 'xs' }),
      skeleton({ lines: 2 }),
    ),
  ),
)

Mouvement

Le scintillement s’arrête pour qui a demandé à son système de réduire les animations — c’est géré dans la feuille de style, sans aucune prop à régler.

Props

PropTypeDéfautDescription
variant'rect' | 'text' | 'circle''rect'La forme du substitut.
widthstring—N’importe quelle largeur CSS.
heightstring—N’importe quelle hauteur CSS.
linesnumber—Rendre ce nombre de lignes de texte, la dernière courte.