Opent in een nieuw tabblad

CSS-lab · Loaders

Indeterminate progress-streep

Een dunne carbon laadbalk bovenaan een paneel, waarin een acid segment heen en weer schiet en onderweg uitrekt. Toegankelijk met role=progressbar.

  • Beginner
  • Pure CSS
  • MIT-licentie
  • @keyframes
  • animation-direction: alternate
  • cubic-bezier
  • overflow: hidden
  • linear-gradient
HTML
<div class="ps-frame">
  <div class="ps-bar" role="progressbar" aria-label="Content wordt geladen" aria-valuetext="Bezig met laden">
    <span class="ps-seg" aria-hidden="true"></span>
  </div>
  <div class="ps-body" aria-hidden="true">
    <span class="ps-line ps-line--lg"></span>
    <span class="ps-line"></span>
    <span class="ps-line ps-line--sm"></span>
  </div>
</div>
CSS
/* Indeterminate progress-streep — prefix .ps- */
.ps-frame {
  --h: 5px;
  --track: #0C0C0D;
  --accent: #C6FF3D;
  --speed: 1.1s;
  width: min(100%, 440px);
  overflow: hidden;
  border: 2px solid #0C0C0D;
  border-radius: 10px;
  background: #FFFFFF;
  box-shadow: 6px 6px 0 #0C0C0D;
}

/* carbon track */
.ps-bar {
  position: relative;
  height: var(--h);
  overflow: hidden;
  background: var(--track);
}

/* acid segment dat heen en weer schiet */
.ps-seg {
  position: absolute;
  top: 0;
  bottom: 0;
  left: 0;
  width: 12%;
  background: var(--accent);
  box-shadow: 0 0 10px var(--accent);
  animation: ps-shuttle var(--speed) cubic-bezier(.65, 0, .35, 1) infinite alternate;
}

@keyframes ps-shuttle {
  0% { left: 0; width: 12%; }
  50% { left: 31%; width: 38%; }
  100% { left: 88%; width: 12%; }
}

/* skeleton-content */
.ps-body {
  display: grid;
  gap: 12px;
  padding: 26px 24px 28px;
}

.ps-line {
  display: block;
  height: 12px;
  width: 82%;
  border-radius: 4px;
  background: linear-gradient(90deg, #ECEAE5 0 40%, #F7F6F2 50%, #ECEAE5 60% 100%) 0 0 / 200% 100%;
  animation: ps-shimmer 1.6s linear infinite;
}

.ps-line--lg {
  height: 22px;
  width: 58%;
  margin-bottom: 6px;
}

.ps-line--sm {
  width: 46%;
}

@keyframes ps-shimmer {
  from { background-position: 100% 0; }
  to { background-position: -100% 0; }
}

@media (prefers-reduced-motion: reduce) {
  .ps-seg { animation-duration: calc(var(--speed) * 3); }
  .ps-line { animation: none; }
}

Wat het is en waar je het gebruikt

Niet elke laadactie verdient een spinner midden op het scherm. Deze indeterminate progress-streep is een dunne balk bovenaan een paneel, kaart of pagina. Een acid segment schiet heen en weer door een carbon track en rekt onderweg uit, zodat het voelt alsof er snelheid in zit. Onder de balk staan drie skeleton-regels met een zachte shimmer, zodat de demo laat zien hoe het eruitziet in een echte interface die nog content ophaalt.

“Indeterminate” betekent dat je niet weet hoe lang het duurt. Gebruik hem bij het ophalen van data, het wisselen van pagina in een webapp of het verwerken van een formulier. Weet je de voortgang wel, gebruik dan een balk met een echte waarde.

Zo werkt het

  • De track: .ps-bar is een balk van --h hoog met overflow: hidden en een carbon achtergrond. Op een lichte pagina geeft acid op carbon veel meer contrast dan acid op wit.
  • Het segment: .ps-seg is absoluut gepositioneerd. @keyframes ps-shuttle animeert left en width tegelijk: smal aan de randen, breed in het midden. Met animation-direction: alternate en een cubic-bezier(.65, 0, .35, 1) remt het segment af bij elke omkeer en schiet het weer weg.
  • De glow: een box-shadow in acid geeft het segment een lichtgevende kop.
  • Skeleton-shimmer: de regels in .ps-body hebben een linear-gradient van 200% breed die met background-position doorschuift.

Aanpassen

Op .ps-frame stel je --h (dikte van de balk), --track, --accent en --speed in. Wil je de balk los bovenaan je pagina, gebruik dan alleen .ps-bar met position: fixed; top: 0; left: 0; right: 0. De skeleton-regels zijn optioneel: laat .ps-body weg als je alleen de streep nodig hebt.

Toegankelijkheid en browsersupport

De balk heeft role="progressbar", een aria-label en aria-valuetext="Bezig met laden". Er staat bewust geen aria-valuenow: zo herkennen hulpmiddelen hem als onbepaald. De skeleton-regels en het segment zijn aria-hidden="true". Met prefers-reduced-motion: reduce beweegt het segment drie keer zo langzaam en stopt de shimmer. Het animeren van left en width is iets minder zuinig dan transform, maar op zo’n klein element merk je dat niet. Werkt in alle actuele browsers.

Verder lezen

Met scroll-driven animations maak je van dezelfde balk een leesvoortgangsbalk die meeloopt met de pagina. Hoe dat werkt, lees je in scroll-driven animations in CSS. Wil je laadmomenten die bij je merk passen, bekijk dan ons webdesign.