Aller au contenu
BDU Cauri, accueilv0.1.0
Composants

Placeholders

Les placeholders sont des blocs gris qui occupent la place du contenu pendant son chargement. Ils évitent que la page « saute » à l’arrivée des données et rassurent sur le fait que le contenu arrive.

Exemple de base#

Une carte avec ses futurs titre, texte et bouton remplacés par des .placeholder. Largeur et hauteur suivent le contenu qu’ils remplacent ; réglez la largeur avec les classes de colonnes ou w-*.

<div class="card" style="max-width: 20rem;" aria-hidden="true">
  <div class="card-body">
    <h5 class="card-title placeholder-glow"><span class="placeholder col-6"></span></h5>
    <p class="card-text placeholder-glow">
      <span class="placeholder col-7"></span>
      <span class="placeholder col-4"></span>
      <span class="placeholder col-4"></span>
      <span class="placeholder col-6"></span>
      <span class="placeholder col-8"></span>
    </p>
    <a class="btn btn-primary disabled placeholder col-6" tabindex="-1" aria-disabled="true"></a>
  </div>
</div>

Largeur#

Les classes de colonnes (col-*) et les utilitaires de dimensionnement (w-25, w-50…) fixent la largeur. Un style en ligne convient pour une valeur exacte.

<span class="placeholder col-6"></span>
<span class="placeholder w-75"></span>
<span class="placeholder" style="width: 25%;"></span>

Couleur#

Par défaut un placeholder prend la couleur du texte (currentColor) avec de la transparence. Changez-la avec les classes de fond.

<span class="placeholder col-12"></span>
<span class="placeholder col-12 bg-primary"></span>
<span class="placeholder col-12 bg-secondary"></span>
<span class="placeholder col-12 bg-info"></span>
<span class="placeholder col-12 bg-warning"></span>
<span class="placeholder col-12 bg-danger"></span>
<span class="placeholder col-12 bg-body-secondary"></span>
<span class="placeholder col-12 bg-dark"></span>

Taille#

La hauteur dépend de la taille de police. Utilisez .placeholder-lg, .placeholder-sm ou .placeholder-xs pour l’ajuster.

<span class="placeholder col-12 placeholder-lg"></span>
<span class="placeholder col-12"></span>
<span class="placeholder col-12 placeholder-sm"></span>
<span class="placeholder col-12 placeholder-xs"></span>

Animation#

.placeholder-glow fait pulser l’opacité des blocs ; .placeholder-wave fait passer une vague de gauche à droite. Placez la classe sur le parent des placeholders.

<p class="placeholder-glow">
  <span class="placeholder col-12"></span>
</p>
<p class="placeholder-wave mb-0">
  <span class="placeholder col-12"></span>
</p>

Squelette d'un relevé#

Combinez les classes pour reproduire la forme d’un contenu réel. L’ensemble est masqué aux lecteurs d’écran et le conteneur est marqué comme occupé.

Chargement des opérations en cours…

<div aria-busy="true">
  <p class="visually-hidden" role="status">Chargement des opérations en cours…</p>
  <ul class="list-group placeholder-glow" aria-hidden="true">
    <li class="list-group-item d-flex justify-content-between">
      <span class="placeholder col-5"></span>
      <span class="placeholder col-2"></span>
    </li>
    <li class="list-group-item d-flex justify-content-between">
      <span class="placeholder col-4"></span>
      <span class="placeholder col-2"></span>
    </li>
    <li class="list-group-item d-flex justify-content-between">
      <span class="placeholder col-6"></span>
      <span class="placeholder col-3"></span>
    </li>
  </ul>
</div>

Remplacer le squelette par le contenu#

Retirez aria-busy et remplacez le contenu quand les données arrivent. Le message role="status" peut alors annoncer la fin du chargement.

async function chargerOperations(zone) {
  zone.setAttribute('aria-busy', 'true');
  const reponse = await fetch('/api/operations');
  const operations = await reponse.json();

  zone.innerHTML = operations
    .map((op) => '<li class="list-group-item">' + op.libelle + ' : ' + op.montant + ' FCFA</li>')
    .join('');
  zone.removeAttribute('aria-busy');
}

Classes

Classes
ClasseRôle
.placeholderBloc de chargement (affichage en ligne, fond currentColor, opacité .5).
.placeholder-xs, .placeholder-sm, .placeholder-lgHauteurs plus petite ou plus grande que celle de la police.
.placeholder-glowAnimation de pulsation (sur le parent).
.placeholder-waveAnimation de vague (sur le parent).
.col-*, .w-*Largeur du placeholder.
.bg-*Couleur du placeholder.

Variables Sass

Variables Sass
VariableValeur par défaut
$placeholder-opacity-max.5
$placeholder-opacity-min.2

Personnalisation#

Les deux variables règlent l’opacité de repos et le creux de l’animation .placeholder-glow.

// Sass : placeholders plus discrets
$placeholder-opacity-max: 0.35;
$placeholder-opacity-min: 0.15;

// CSS : placeholder gris bleuté pour une zone précise
.squelette .placeholder {
  background-color: #8A9BB5;
  border-radius: 0.25rem;
}

Bonnes pratiques

À faire

  • Reproduisez la forme du contenu final (même nombre de lignes, mêmes largeurs approximatives).
  • Marquez le squelette aria-hidden="true" et ajoutez un texte d’état pour les lecteurs d’écran.
  • Utilisez aria-busy="true" sur la zone en cours de chargement, puis retirez-le à l’arrivée du contenu.
  • Réservez les placeholders aux chargements d’au moins quelques centaines de millisecondes.

À éviter

  • N’affichez pas de placeholders sans fin : prévoyez un message d’erreur si le chargement échoue.
  • N’utilisez pas à la fois un spinner et un squelette pour la même zone.
  • Ne placez pas de texte lisible à l’intérieur des placeholders.

Accessibilité

  • Les placeholders sont purement visuels : cachez-les avec aria-hidden="true" pour que les lecteurs d’écran ne parlent pas de blocs vides.
  • Un bouton placeholder doit avoir .disabled, tabindex="-1" et aria-disabled="true" pour ne pas recevoir le focus.
  • Annoncez le chargement avec un texte visually-hidden dans un élément role="status".
  • Les animations placeholder-glow et placeholder-wave ne sont pas coupées automatiquement par prefers-reduced-motion : si votre public le demande, neutralisez-les avec @media (prefers-reduced-motion: reduce) { .placeholder-glow .placeholder, .placeholder-wave { animation: none; } }.
Charte provisoire, déduite du site public de la BDU CI. Elle sera remplacée par la charte officielle.