6 loading animations in pure CSS
Six loading animations, each one element (or a few dots) and a few lines of CSS. No images, no JavaScript.
UI loop
6 loading animations, pure CSS
Ring
Bounce
Equalizer
Ripple
Orbit
Morph
Sundry Millsundrymill.com/library
Everything in the preview is live. Try it.
The code, one by one
Ring
The classic spinner: one coloured quarter going round.
HTML
<span class="ld-ring" role="status" aria-label="Loading"></span>
CSS
.ld-ring {
display: inline-block;
width: 44px;
height: 44px;
border-radius: 50%;
border: 5px solid rgba(23, 32, 44, .15);
border-top-color: #FF7A2F;
animation: ld-ring .9s linear infinite;
}
@keyframes ld-ring { to { transform: rotate(1turn); } }
Bounce
Three dots hop one after another, like someone typing.
HTML
<span class="ld-dots" role="status" aria-label="Loading"><i></i><i></i><i></i></span>
CSS
.ld-dots { display: inline-flex; gap: 8px; }
.ld-dots i {
width: 12px;
height: 12px;
border-radius: 50%;
background: #17202C;
animation: ld-dots 1s cubic-bezier(.65, 0, .35, 1) infinite;
}
.ld-dots i:nth-child(2) { animation-delay: .15s; }
.ld-dots i:nth-child(3) { animation-delay: .3s; }
@keyframes ld-dots {
0%, 60%, 100% { transform: translateY(0); opacity: .45; }
30% { transform: translateY(-12px); opacity: 1; }
}
Equalizer
Five bars rising and falling. Good for anything to do with sound.
HTML
<span class="ld-bars" role="status" aria-label="Loading"><i></i><i></i><i></i><i></i><i></i></span>
CSS
.ld-bars { display: inline-flex; align-items: center; gap: 5px; height: 40px; }
.ld-bars i {
width: 6px;
height: 100%;
border-radius: 3px;
background: #2F55D4;
animation: ld-bars 1s ease-in-out infinite;
}
.ld-bars i:nth-child(2) { animation-delay: -.8s; }
.ld-bars i:nth-child(3) { animation-delay: -.6s; }
.ld-bars i:nth-child(4) { animation-delay: -.4s; }
.ld-bars i:nth-child(5) { animation-delay: -.2s; }
@keyframes ld-bars {
0%, 100% { transform: scaleY(.3); }
50% { transform: scaleY(1); }
}
Ripple
Two rings ripple outward. Calm, for longer waits.
HTML
<span class="ld-pulse" role="status" aria-label="Loading"></span>
CSS
.ld-pulse { position: relative; display: inline-block; width: 44px; height: 44px; }
.ld-pulse::before, .ld-pulse::after {
content: "";
position: absolute;
inset: 0;
border-radius: 50%;
border: 3px solid #FF7A2F;
animation: ld-pulse 1.6s cubic-bezier(.05, .7, .1, 1) infinite;
}
.ld-pulse::after { animation-delay: .8s; }
@keyframes ld-pulse {
from { transform: scale(.2); opacity: 1; }
to { transform: scale(1); opacity: 0; }
}
Orbit
A dot circles a dashed track, like a small planet.
HTML
<span class="ld-orbit" role="status" aria-label="Loading"></span>
CSS
.ld-orbit {
position: relative;
display: inline-block;
width: 44px;
height: 44px;
border-radius: 50%;
border: 2px dashed rgba(23, 32, 44, .35);
animation: ld-orbit 1.4s linear infinite;
}
.ld-orbit::after {
content: "";
position: absolute;
top: -7px;
left: 50%;
width: 12px;
height: 12px;
margin-left: -6px;
border-radius: 50%;
background: #17202C;
}
@keyframes ld-orbit { to { transform: rotate(1turn); } }
Morph
A square turns a quarter and rounds into a circle, then back.
HTML
<span class="ld-morph" role="status" aria-label="Loading"></span>
CSS
.ld-morph {
display: inline-block;
width: 40px;
height: 40px;
border-radius: 4px;
background: #FFB23F;
animation: ld-morph 1.6s cubic-bezier(.65, 0, .35, 1) infinite;
}
@keyframes ld-morph {
0%, 100% { border-radius: 4px; transform: rotate(0) scale(1); }
50% { border-radius: 50%; transform: rotate(90deg) scale(.8); }
}
How to use it
- Every loader carries role="status" and an aria-label, so a screen reader says "Loading" once instead of nothing.
- Show a loader only after about 300 milliseconds. Fast responses then never flash a spinner at all.
- Wrap the animations in a prefers-reduced-motion check if the wait can be long. A still ring with the word "Loading" is fine.
Showing an interaction like this to a client or in a tutorial? Framok records your screen and zooms in on every click for you.
Free to use in personal and commercial work. No credit needed, though a link back is always nice.