A keyframes rule names points in an animation cycle. The animation properties select that cycle, its duration, and how many times it runs.
CSS keyframes: keep repeating motion bounded and optional
How the rule works
A small loading marker on a report card may rotate while an authorized request is pending. The text beside it must say that the report is loading, because motion alone is not a status message. Keep the animation on a small element, not an entire panel of text, and stop it when the request completes or fails. A reduced-motion preference removes the rotation while leaving the marker and status text visible. Avoid an infinite animation on content that is already complete; it wastes attention and can make the interface appear stuck.
@keyframes report-wait { to { transform: rotate(1turn); } }
.report-loading__mark { inline-size: 1.25rem; aspect-ratio: 1; border: 2px solid currentColor; border-inline-start-color: transparent; border-radius: 50%; animation: report-wait 900ms linear infinite; }
@media (prefers-reduced-motion: reduce) {
.report-loading__mark { animation: none; border-inline-start-color: currentColor; }
}Cost and verification
A small transform animation is usually less expensive than animating layout dimensions, but a screen full of perpetual markers still consumes resources. Profile the actual page if many requests can run together. The rule does not start or stop the loading state; application logic must update the element and its text. Check that the marker remains visible in forced colors and that the completed state does not retain the animation class.
Common Mistakes
- Do not use infinite motion as the only progress announcement.
- Do not leave a spinner running after a failed request.
- Do not ignore reduced-motion settings for repeated decoration.
Connected lessons
- CSS Interaction and Accessibility
- CSS reduced motion: remove nonessential movement at the source
- CSS transitions and transforms: animate a specific visual property
- HTML status region: announce a changed result without stealing focus
