Chargement✨ Premium

Progress Bar

Une barre de 200 × 6 px ; un pseudo-élément ::after de 80 px (40 % du rail) en dégradé indigo–fuchsia glisse de translateX(−100 %) à translateX(350 %) en 1,5 s ease-in-out, infini. Aucun JavaScript — l'intégralité du mouvement tient en un @keyframes et un sélecteur ::after.

CSSLinear

Vous aurez accès à la démo interactive avec un compte gratuit.

Cet effet fait partie d'Effect.Labs — 811 effets vanilla, une partie gratuite, une partie premium. Chargement comprend 29 effets, dont 4 gratuits. Découvrir la catégorie →

3 exemples d'usage

Bouton d'envoi — formulaire en attente de réponse serveur — Progress Bar exemple 1

① Bouton d'envoi — formulaire en attente de réponse serveur

QuandUn formulaire de contact ou de paiement : au clic, le texte du bouton disparaît et la barre remplace son fond pendant la requête. Elle cède la place au résultat (succès ou erreur) dès la réponse.
PourquoiLa barre occupe exactement l'espace du bouton, sans icône tournante qui s'ajoute. L'indicateur indéterminé est juste — on ignore combien de temps prend la réponse du serveur. La course gauche-droite suit la direction de lecture et suggère une progression vers la validation.
Réglageswidth: 100% (hérite du bouton, typiquement 140–200 px), height: 4px pour rester discret, border-radius: 0 0 6px 6px si le bouton a un arrondi de 6 px ; pilule width: 50%.
Bord haut de la fenêtre — navigation d'une page à l'autre — Progress Bar exemple 2

② Bord haut de la fenêtre — navigation d'une page à l'autre

QuandUn site ou une application à navigation côté client (documentation, back-office, boutique) : l'utilisateur clique un lien du menu et la page courante reste affichée le temps que la suivante arrive. La barre est collée au bord supérieur de la fenêtre, sur toute sa largeur, hors de tout conteneur ; elle disparaît au rendu de la nouvelle page.
PourquoiC'est l'usage d'origine de cette forme — celui des grands sites et des routeurs front (Turbo, Nuxt, Next). Une barre de 4 px contre le bord ne réserve aucun espace et ne recouvre rien : un spinner ou un squelette obligerait à choisir un emplacement dans une page qui n'existe pas encore, ou à masquer celle qui existe. Étirée à la largeur de la fenêtre, elle donne à la pilule une course longue que l'œil capte en vision périphérique sans quitter ce qu'il lisait. Et l'attente d'une page — réseau puis rendu — est de durée inconnue : l'indicateur indéterminé est le seul honnête.
Réglagesposition: fixed; top: 0; left: 0; z-index: 1000 sur .loader-bar, width: 100% (la fenêtre entière : sur 540 px, la pilule à 30% mesure 162 px), height: 4px (contre 6 px par défaut), border-radius: 0 sur le rail et sur la pilule — un arrondi n'a pas de sens contre un bord ; durée, courbe, rail et dégradé par défaut (1,5 s ease-in-out, rgba(99, 102, 241, .2), indigo → fuchsia).
Génération IA — traitement d'un prompt en attente de streaming — Progress Bar exemple 3

③ Génération IA — traitement d'un prompt en attente de streaming

QuandUne interface LLM ou de complétion automatique : l'utilisateur valide son prompt et attend les premiers tokens. La barre est placée sous la zone de saisie ou au-dessus de la zone de réponse.
PourquoiLa durée d'une génération est inconnue et variable — l'indicateur indéterminé est le seul honnête. Une fois le streaming démarré (premiers tokens affichés), la barre cède la place au texte. La forme fine ne concurrence pas la zone de texte.
Réglagesanimation-duration: 2s et ease-in-out remplacé par linear pour un défilement régulier sans pulsation visible ; gradient linear-gradient(90deg, #6366f1, #818cf8) (bleu-violet, connotation tech) ; width: 100%.

Comment ça marche

Le code expose un seul élément : .loader-bar, 200 × 6 px, fond rgba(99, 102, 241, .2) (indigo à 20 % d'opacité), border-radius: 3px, overflow: hidden. Il n'a aucun descendant dans le HTML vendu ; tout le mouvement vient du pseudo-élément ::after. Celui-ci fait 40 % de la largeur du rail — soit 80 × 6 px — et affiche le dégradé linear-gradient(90deg, #6366f1, #d946ef) (indigo → fuchsia).

barProgress déplace la pilule de translateX(−100 %) à translateX(350 %). Ces valeurs sont relatives à sa propre largeur (80 px) : elle entre par −80 px (hors du rail côté gauche) et sort à 280 px du bord gauche du rail (hors du rail côté droit, le rail ne faisant que 200 px). Le déplacement total est de 360 px. La durée est 1,5 s, la courbe ease-in-out : la pilule accélère en entrant depuis la gauche, atteint sa vitesse maximale au centre et ralentit avant de disparaître à droite. Mesuré dans Chromium : −67,8 px à 200 ms (toujours hors du rail côté gauche), −0,7 px à 500 ms (pilule qui entre dans la zone visible). La boucle est infinite, délai 0 s : lors du redémarrage, la pilule se retrouve instantanément en dehors du rail côté gauche — la coupure est invisible grâce à overflow: hidden.

Il n'y a aucun JavaScript dans le code vendu. Arrêter ou déclencher l'animation demande uniquement de basculer animation-play-state: paused / running sur .loader-bar::after, ce qui s'obtient en ajoutant ou retirant une classe sur le rail. La largeur 200px est fixe et non responsive : sur un conteneur plus étroit la barre déborde ; sur un conteneur plus large, elle reste centrée mais ne s'étire pas. Remplacez par width: 100% pour qu'elle suive son parent.

Accessibilité

  • prefers-reduced-motion absent du code : mesuré dans Playwright avec reducedMotion: 'reduce', la pilule est à −68,3 px à 200 ms et à −2,1 px à 500 ms — l'animation tourne sans changement. Ajoutez @media (prefers-reduced-motion: reduce) { .loader-bar::after { animation: none; } }.
  • Aucun marqueur d'accessibilité : la barre est un div vide sans role, aria-live, aria-busy ni texte alternatif. Pour un lecteur d'écran, l'état de chargement est invisible. Ajoutez au minimum un élément frère avec role="status" aria-live="polite" et un texte masqué visuellement (clip-rect ou classe sr-only) : « Chargement en cours… ».
  • Le rail est purement décoratif : posez aria-hidden="true" sur .loader-bar et confiez l'état à un élément dédié. Si la barre est intégrée dans un bouton (bouton en cours d'envoi), l'attribut aria-busy="true" va sur le bouton, pas sur la barre.
  • Contraste : la pilule (#6366f1 → #d946ef) sur fond #0a0a0f mesure 3,4:1 pour l'indigo et 3,8:1 pour le fuchsia — au-dessus du seuil des éléments graphiques (3:1). Sur fond blanc, ces valeurs tombent à 2,8:1 et 3,4:1 ; descendez la luminosité ou renforcez la saturation pour tenir le seuil sur fond clair.

Compatibilité navigateur

Requiert @keyframes, translateX(), linear-gradient(), border-radius, overflow: hidden et le pseudo-élément ::after avec content: "". Toutes ces propriétés sont disponibles depuis Chrome 26, Firefox 16, Safari 7. Aucune dépendance.

Chrome 26+✓ Complet
Firefox 16+✓ Complet
Safari 7+✓ Complet
Edge 12+✓ Complet
Mobile iOS 7+✓ Complet
Android Chrome✓ Complet

Sans animation CSS (navigateurs très anciens), le rail s'affiche vide : la pilule est dans le DOM (::after généré par le CSS) mais immobile à sa position initiale (translateX(−100 %)), donc hors du rail et invisible. Sans linear-gradient (IE 9, ancienne syntaxe), la pilule s'affiche avec un fond transparent — invisible. Sans CSS, le rail est un div vide.

Le code

Structure HTML à coller dans votre page (CSS + JS disponibles avec un compte premium) :

index.html — structure
<div class="loader-bar"></div>
🔒 Débloquer le code complet — à partir de 2,99 € le 1er mois

HTML + CSS + JS complet, prêt à coller — avec des centaines d'effets premium.

Personnaliser

Options passées à l'API ou attributs data-* :

Option / propriétéDéfautEffet
Largeur du rail (CSS — .loader-bar, width) 200px Largeur totale de la piste. Changez en 100% pour qu'elle suive son parent ; la course de la pilule s'adapte automatiquement car sa largeur est en pourcentage.
Épaisseur (CSS — .loader-bar, height) 6px Hauteur partagée par le rail et la pilule (::after height: 100%). 4px pour un indicateur intégré dans un bouton ; 8px pour un en-tête de page plus visible.
Couleur du rail (CSS — .loader-bar, background) rgba(99, 102, 241, .2) Fond de la piste. Reprenez la teinte principale à 15–25 % d'opacité pour rester dans la même famille chromatique que la pilule.
Largeur de la pilule (CSS — .loader-bar::after, width) 40 % (= 80 px sur un rail de 200 px) Fraction du rail occupée par la pilule. 25% = course plus longue, effet plus vif ; 60% = pilule large qui couvre presque le rail au passage.
Gradient de la pilule (CSS — .loader-bar::after, background) linear-gradient(90deg, #6366f1, #d946ef) Couleur de la pilule. Une couleur unie (background: #6366f1) ou un dégradé inversé (#d946ef, #6366f1) pour une direction visuelle opposée.
Durée du cycle (CSS — .loader-bar::after, animation-duration) 1.5s Temps d'un aller complet. 0.8s = chargement nerveux (requête réseau) ; 3s = traitement lent (calcul, génération). Remplacez aussi ease-in-out par linear pour une vitesse constante au-delà de 2 s.
Arrondi (CSS — .loader-bar et .loader-bar::after, border-radius) 3px Les deux doivent partager la même valeur pour des extrémités cohérentes. 0 = barre angulaire ; 9999px = pilule ovale sur rail arrondi.

FAQ

Oui. C'est la définition d'une barre indéterminée : elle ne représente pas un pourcentage d'avancement, elle signale qu'une opération est en cours sans en connaître la durée. Le comportement opposé — une barre qui s'étire de 0 à 100 % — demande de connaître la progression réelle et d'animer width en JavaScript. Pour ce comportement, ajoutez une variable CSS --progress sur .loader-bar::after et modifiez sa valeur depuis votre code.
Deux approches courantes : (1) animation-play-state: paused sur .loader-bar::after fige la pilule à sa position actuelle — le mouvement s'arrête mais la barre reste visible. (2) display: none ou visibility: hidden sur .loader-bar la retire visuellement. Pour une transition soignée, ajoutez opacity: 0; transition: opacity .3s sur .loader-bar et appliquez la classe via JavaScript dès la réponse reçue.
La Circular Progress (fx-0432) est un SVG de 60 × 60 px dont l'animation porte sur stroke-dashoffset — l'arc passe de 157 à 0 puis à −157 en 2 s (entrée puis sortie de l'arc). Le format carré convient à un indicateur isolé ou placé à côté d'un libellé. La Progress Bar (fx-0424) est horizontale, 200 × 6 px, et peut s'étirer à 100 % de son parent : elle se pose au-dessus ou en dessous d'un contenu (tableau, bouton, zone de texte) et prend toute la largeur disponible sans ajouter de hauteur.