De markup komt mee met de CSS
Een spinner is één element en een rand. Een loader met stippen is drie kinderen met verspringende animatievertragingen, en geen enkele hoeveelheid CSS maakt drie stippen uit een lege <div> tenzij je allebei de pseudo-elementen wilt opofferen en dan nog een stip tekortkomt. Allebei de vakken zijn hier dus de uitvoer: de HTML en de stylesheet, samen, want een generator die alleen de regel aanreikt heeft de makkelijke helft gedaan.
De markup draagt role="status" en een label. Dat is geen versiering: zonder dat kondigt een schermlezer helemaal niets aan terwijl je pagina laadt, en blijft het stil waar een ziende gebruiker beweging ziet. role="status" is een beleefde live region, dus hij wordt tussen andere meldingen door voorgelezen in plaats van er dwars doorheen.
Beperkte beweging wordt gegenereerd, niet aangeboden
Een spinner die onophoudelijk draait is een van de duidelijkste prikkels voor vestibulaire aandoeningen, en die treffen volgens de eigen cijfers van de NIH op enig moment ruwweg 35% van de volwassenen boven de 40 in de Verenigde Staten. Gebruikers die het nodig hebben zetten prefers-reduced-motion: reduce op het niveau van het besturingssysteem, en elke export van deze pagina houdt zich daaraan.
Hoe hij zich eraan houdt is het deel waar over te twisten valt. De gangbare aanpak is animation: none, en dat laat een stilstaande ring op het scherm achter en vertelt de gebruiker niets. Dit laat de loader in plaats daarvan in 2 seconden in en uit faden: geen rotatie, geen verplaatsing, niets dat door het gezichtsveld beweegt, en toch een duidelijk "er wordt aan gewerkt". Dat is de geest van de media query in plaats van de letter.
Hoe elke familie is opgebouwd
De spinner is een volledige rand in de kleur op 20% alpha met de bovenrand op volle sterkte, eeuwig ronddraaiend. Eén element, geen pseudo-elementen. Stippen en balken laten drie kinderen een derde en een zesde van de cyclus verspringen, en dat is wat ze als één golf laat lezen in plaats van als drie losse animaties. Shimmer schuift een verloop met background-position over een achtergrondgrootte van 200%, dus het werkt op elke breedte zonder pseudo-element en zonder de container te kennen.
Veelvoorkomende problemen
- De spinner is een gevulde schijf. De rand is dikker dan de straal. De dikte is hier daarom begrensd op de helft van de maat.
- Hij springt aan het eind van elke ronde. De keyframes sluiten niet: de waarde op 100% moet gelijk zijn aan die op 0%. De curves voor stuiteren en rekken keren daarom allebei terug naar hun begintransformatie.
- De loader blijft zichzelf aankondigen. Een live region die in de DOM blijft staan kondigt opnieuw aan als zijn inhoud verandert. Haal het element weg als het laden klaar is in plaats van het met
display: nonete verbergen. - De rest van de pagina hapert terwijl hij draait. Alleen
transformenopacityanimeren op de compositor. Een loader diewidth,topofborder-widthanimeert dwingt elk frame een lay-outronde af. Alle vijf de families hier animeren alleen properties die veilig zijn voor de compositor, behalve shimmer, die een achtergrondpositie animeert. Dat is goedkoop, maar het tekent opnieuw in plaats van samen te stellen.
Veelgestelde vragen
Wanneer moet ik überhaupt een loader tonen?
Vanaf ruwweg één seconde. Onder ongeveer 300ms leest een spinner die opflitst en verdwijnt als een storing en voelt de interface minder betrouwbaar in plaats van meer. Het gebruikelijke patroon is een vertraging voor het tonen en een minimale toontijd zodra hij er staat, zodat hij nooit knippert.
Spinner of skelet?
Een skelet waar je de vorm kent van wat er komt, een spinner waar je die niet kent. Een skelet dat bij de uiteindelijke lay-out past haalt de verschuiving weg als de inhoud aankomt, en dat is de grotere winst: het geeft niet alleen voortgang aan, het houdt ook de lay-out stabiel.
Kan ik een CSS-variabele voor de kleur gebruiken?
Ja. Vervang de hexwaarden door var(--brand). Het enige om op te letten is het vage spoor van de spinner, dat als een hex van acht cijfers met een alfa-achtervoegsel geschreven is; gebruik met een variabele in plaats daarvan color-mix(in oklab, var(--brand) 20%, transparent).
Draait het voorbeeld dezelfde code die ik kopieer?
Ja, letterlijk. De stylesheet in het vak hierboven is de gegenereerde, afgebakend tot de voorbeeldcontainer. Niets aan de animatie is voor de weergave nagebouwd, en dat is de enige manier om zeker te weten dat wat je ziet is wat je plakt.