Letters drop in one by one, squash on impact, bounce and come to rest in a tumbled heap, until a trapdoor floor swings open and drops them all. Each fall is a keyframe built from a short table.
Also known as: falling letters animation, letters falling physics css, gravity text animation.
<div class="txt-letters-pile-up" aria-label="Gravity"><span aria-hidden="true"><b class="txt-letters-pile-up-l0">G</b><b class="txt-letters-pile-up-l1">R</b><b class="txt-letters-pile-up-l2">A</b><b class="txt-letters-pile-up-l3">V</b><b class="txt-letters-pile-up-l4">I</b><b class="txt-letters-pile-up-l5">T</b><b class="txt-letters-pile-up-l6">Y</b></span></div>
.txt-letters-pile-up {
--c: var(--txt-color, #3b82f6);
font-size: var(--txt-size, 32px);
font-family: system-ui, sans-serif;
font-weight: 700;
line-height: 1.2;
position: relative;
width: 8em;
height: 5.2em;
overflow: hidden;}
/* the floor: two halves hinged at the outside edges */
.txt-letters-pile-up::before,
.txt-letters-pile-up::after {
content: "";
position: absolute;
bottom: 0.5em;
width: calc(50% - 0.6em);
height: 0.09em;
border-radius: 0.05em;
background: color-mix(in srgb, currentColor 30%, transparent);
animation: txt-letters-pile-up-door 6.2s infinite;
}
.txt-letters-pile-up::before { left: 0.6em; transform-origin: 0 50%; --s: 1; }
.txt-letters-pile-up::after { right: 0.6em; transform-origin: 100% 50%; --s: -1; }
.txt-letters-pile-up b {
position: absolute;
left: 50%;
bottom: calc(0.59em / 1.75);
font-size: 1.75em;
font-weight: 900;
line-height: 0.76;
transform-origin: 50% 100%;
}
.txt-letters-pile-up b:last-child { color: var(--c); }
.txt-letters-pile-up .txt-letters-pile-up-l0 { animation: txt-letters-pile-up-l0 6.2s infinite; }
.txt-letters-pile-up .txt-letters-pile-up-l1 { animation: txt-letters-pile-up-l1 6.2s infinite; }
.txt-letters-pile-up .txt-letters-pile-up-l2 { animation: txt-letters-pile-up-l2 6.2s infinite; }
.txt-letters-pile-up .txt-letters-pile-up-l3 { animation: txt-letters-pile-up-l3 6.2s infinite; }
.txt-letters-pile-up .txt-letters-pile-up-l4 { animation: txt-letters-pile-up-l4 6.2s infinite; }
.txt-letters-pile-up .txt-letters-pile-up-l5 { animation: txt-letters-pile-up-l5 6.2s infinite; }
.txt-letters-pile-up .txt-letters-pile-up-l6 { animation: txt-letters-pile-up-l6 6.2s infinite; }
@keyframes txt-letters-pile-up-l0 {
0%, 2.42% { translate: calc(-1.2em - 50%) -4.6em; rotate: -40deg; scale: 1; opacity: 1; animation-timing-function: cubic-bezier(0.55, 0, 1, 0.45); }
9.19% { translate: calc(-1.2em - 50%) 0em; rotate: -8deg; scale: 1.14 0.86; animation-timing-function: cubic-bezier(0.2, 0.7, 0.4, 1); }
11.77% { translate: calc(-1.2em - 50%) -0.2em; rotate: -4.8deg; scale: 0.96 1.04; animation-timing-function: cubic-bezier(0.5, 0, 0.8, 0.5); }
14.35% { translate: calc(-1.2em - 50%) 0em; rotate: -8deg; scale: 1.04 0.96; animation-timing-function: ease-out; }
16.94%, 72.58% { translate: calc(-1.2em - 50%) 0em; rotate: -8deg; scale: 1; opacity: 1; animation-timing-function: cubic-bezier(0.5, 0, 0.9, 0.4); }
82.26% { translate: calc(-1.2em - 50%) 3.6em; rotate: -36deg; opacity: 0; }
82.58%, 100% { translate: calc(-1.2em - 50%) -4.6em; rotate: -40deg; opacity: 0; }
}
@keyframes txt-letters-pile-up-l1 {
0%, 7.58% { translate: calc(-0.4em - 50%) -4.6em; rotate: 35deg; scale: 1; opacity: 1; animation-timing-function: cubic-bezier(0.55, 0, 1, 0.45); }
14.35% { translate: calc(-0.4em - 50%) 0em; rotate: 6deg; scale: 1.14 0.86; animation-timing-function: cubic-bezier(0.2, 0.7, 0.4, 1); }
16.94% { translate: calc(-0.4em - 50%) -0.2em; rotate: 3.6deg; scale: 0.96 1.04; animation-timing-function: cubic-bezier(0.5, 0, 0.8, 0.5); }
19.52% { translate: calc(-0.4em - 50%) 0em; rotate: 6deg; scale: 1.04 0.96; animation-timing-function: ease-out; }
22.1%, 72.58% { translate: calc(-0.4em - 50%) 0em; rotate: 6deg; scale: 1; opacity: 1; animation-timing-function: cubic-bezier(0.5, 0, 0.9, 0.4); }
82.26% { translate: calc(-0.4em - 50%) 3.6em; rotate: 34deg; opacity: 0; }
82.58%, 100% { translate: calc(-0.4em - 50%) -4.6em; rotate: 35deg; opacity: 0; }
}
@keyframes txt-letters-pile-up-l2 {
0%, 12.74% { translate: calc(0.42em - 50%) -4.6em; rotate: -30deg; scale: 1; opacity: 1; animation-timing-function: cubic-bezier(0.55, 0, 1, 0.45); }
19.52% { translate: calc(0.42em - 50%) 0em; rotate: -4deg; scale: 1.14 0.86; animation-timing-function: cubic-bezier(0.2, 0.7, 0.4, 1); }
22.1% { translate: calc(0.42em - 50%) -0.2em; rotate: -2.4deg; scale: 0.96 1.04; animation-timing-function: cubic-bezier(0.5, 0, 0.8, 0.5); }
24.68% { translate: calc(0.42em - 50%) 0em; rotate: -4deg; scale: 1.04 0.96; animation-timing-function: ease-out; }
27.26%, 72.58% { translate: calc(0.42em - 50%) 0em; rotate: -4deg; scale: 1; opacity: 1; animation-timing-function: cubic-bezier(0.5, 0, 0.9, 0.4); }
82.26% { translate: calc(0.42em - 50%) 3.6em; rotate: -32deg; opacity: 0; }
82.58%, 100% { translate: calc(0.42em - 50%) -4.6em; rotate: -30deg; opacity: 0; }
}
@keyframes txt-letters-pile-up-l3 {
0%, 17.9% { translate: calc(1.2em - 50%) -4.6em; rotate: 50deg; scale: 1; opacity: 1; animation-timing-function: cubic-bezier(0.55, 0, 1, 0.45); }
24.68% { translate: calc(1.2em - 50%) 0em; rotate: -16deg; scale: 1.14 0.86; animation-timing-function: cubic-bezier(0.2, 0.7, 0.4, 1); }
27.26% { translate: calc(1.2em - 50%) -0.2em; rotate: -9.6deg; scale: 0.96 1.04; animation-timing-function: cubic-bezier(0.5, 0, 0.8, 0.5); }
29.84% { translate: calc(1.2em - 50%) 0em; rotate: -16deg; scale: 1.04 0.96; animation-timing-function: ease-out; }
32.42%, 72.58% { translate: calc(1.2em - 50%) 0em; rotate: -16deg; scale: 1; opacity: 1; animation-timing-function: cubic-bezier(0.5, 0, 0.9, 0.4); }
82.26% { translate: calc(1.2em - 50%) 3.6em; rotate: -44deg; opacity: 0; }
82.58%, 100% { translate: calc(1.2em - 50%) -4.6em; rotate: 50deg; opacity: 0; }
}
@keyframes txt-letters-pile-up-l4 {
0%, 23.06% { translate: calc(-0.8em - 50%) -4.6em; rotate: 60deg; scale: 1; opacity: 1; animation-timing-function: cubic-bezier(0.55, 0, 1, 0.45); }
29.84% { translate: calc(-0.8em - 50%) -0.72em; rotate: -14deg; scale: 1.14 0.86; animation-timing-function: cubic-bezier(0.2, 0.7, 0.4, 1); }
32.42% { translate: calc(-0.8em - 50%) -0.92em; rotate: -8.4deg; scale: 0.96 1.04; animation-timing-function: cubic-bezier(0.5, 0, 0.8, 0.5); }
35% { translate: calc(-0.8em - 50%) -0.72em; rotate: -14deg; scale: 1.04 0.96; animation-timing-function: ease-out; }
37.58%, 72.58% { translate: calc(-0.8em - 50%) -0.72em; rotate: -14deg; scale: 1; opacity: 1; animation-timing-function: cubic-bezier(0.5, 0, 0.9, 0.4); }
82.26% { translate: calc(-0.8em - 50%) 2.88em; rotate: -42deg; opacity: 0; }
82.58%, 100% { translate: calc(-0.8em - 50%) -4.6em; rotate: 60deg; opacity: 0; }
}
@keyframes txt-letters-pile-up-l5 {
0%, 28.23% { translate: calc(0.04em - 50%) -4.6em; rotate: -45deg; scale: 1; opacity: 1; animation-timing-function: cubic-bezier(0.55, 0, 1, 0.45); }
35% { translate: calc(0.04em - 50%) -0.74em; rotate: 12deg; scale: 1.14 0.86; animation-timing-function: cubic-bezier(0.2, 0.7, 0.4, 1); }
37.58% { translate: calc(0.04em - 50%) -0.94em; rotate: 7.2deg; scale: 0.96 1.04; animation-timing-function: cubic-bezier(0.5, 0, 0.8, 0.5); }
40.16% { translate: calc(0.04em - 50%) -0.74em; rotate: 12deg; scale: 1.04 0.96; animation-timing-function: ease-out; }
42.74%, 72.58% { translate: calc(0.04em - 50%) -0.74em; rotate: 12deg; scale: 1; opacity: 1; animation-timing-function: cubic-bezier(0.5, 0, 0.9, 0.4); }
82.26% { translate: calc(0.04em - 50%) 2.86em; rotate: 40deg; opacity: 0; }
82.58%, 100% { translate: calc(0.04em - 50%) -4.6em; rotate: -45deg; opacity: 0; }
}
@keyframes txt-letters-pile-up-l6 {
0%, 33.39% { translate: calc(-0.4em - 50%) -4.6em; rotate: 70deg; scale: 1; opacity: 1; animation-timing-function: cubic-bezier(0.55, 0, 1, 0.45); }
40.16% { translate: calc(-0.4em - 50%) -1.46em; rotate: -22deg; scale: 1.14 0.86; animation-timing-function: cubic-bezier(0.2, 0.7, 0.4, 1); }
42.74% { translate: calc(-0.4em - 50%) -1.66em; rotate: -13.2deg; scale: 0.96 1.04; animation-timing-function: cubic-bezier(0.5, 0, 0.8, 0.5); }
45.32% { translate: calc(-0.4em - 50%) -1.46em; rotate: -22deg; scale: 1.04 0.96; animation-timing-function: ease-out; }
47.9%, 72.58% { translate: calc(-0.4em - 50%) -1.46em; rotate: -22deg; scale: 1; opacity: 1; animation-timing-function: cubic-bezier(0.5, 0, 0.9, 0.4); }
82.26% { translate: calc(-0.4em - 50%) 2.14em; rotate: -50deg; opacity: 0; }
82.58%, 100% { translate: calc(-0.4em - 50%) -4.6em; rotate: 70deg; opacity: 0; }
}
@keyframes txt-letters-pile-up-door {
0%, 71.29% { rotate: 0deg; animation-timing-function: cubic-bezier(0.5, 0, 0.9, 0.5); }
74.52% { rotate: calc(var(--s) * 64deg); animation-timing-function: ease-out; }
77.1%, 88.71% { rotate: calc(var(--s) * 58deg); animation-timing-function: cubic-bezier(0.34, 1.4, 0.64, 1); }
96.77%, 100% { rotate: 0deg; }
}
@media (prefers-reduced-motion: reduce) {
.txt-letters-pile-up::before, .txt-letters-pile-up::after { animation: none; }
.txt-letters-pile-up .txt-letters-pile-up-l0 { animation: none; translate: calc(-1.2em - 50%) 0em; rotate: -8deg; }
.txt-letters-pile-up .txt-letters-pile-up-l1 { animation: none; translate: calc(-0.4em - 50%) 0em; rotate: 6deg; }
.txt-letters-pile-up .txt-letters-pile-up-l2 { animation: none; translate: calc(0.42em - 50%) 0em; rotate: -4deg; }
.txt-letters-pile-up .txt-letters-pile-up-l3 { animation: none; translate: calc(1.2em - 50%) 0em; rotate: -16deg; }
.txt-letters-pile-up .txt-letters-pile-up-l4 { animation: none; translate: calc(-0.8em - 50%) -0.72em; rotate: -14deg; }
.txt-letters-pile-up .txt-letters-pile-up-l5 { animation: none; translate: calc(0.04em - 50%) -0.74em; rotate: 12deg; }
.txt-letters-pile-up .txt-letters-pile-up-l6 { animation: none; translate: calc(-0.4em - 50%) -1.46em; rotate: -22deg; }
}
@media (prefers-reduced-motion: reduce) {
.txt-letters-pile-up, .txt-letters-pile-up *, .txt-letters-pile-up::before, .txt-letters-pile-up::after, .txt-letters-pile-up *::before, .txt-letters-pile-up *::after {
animation-duration: 0.01ms !important;
animation-iteration-count: 1 !important;
transition-duration: 0.01ms !important;
}
}--txt-color on the element or a parent.
Currently previewing #3b82f6.--txt-size. Every other dimension is in
em, so the whole thing scales together. Currently previewing 40px.transition or animation
shorthand. Staggered delays are relative, so they keep their rhythm.