25 CSS Text Animations 14 / 25
CSS Perspective Text Rotation Animation
Text rotates continuously around its X-axis in 3D perspective space, creating a rolling barrel or tumbling-through-space headline effect.
The code
<div class="ta-14">
<div class="ta-14__stage">
<p class="ta-14__eyebrow">Into the</p>
<div class="ta-14__scene">
<h2 class="ta-14__text">VOID</h2>
</div>
<p class="ta-14__sub">perspective · rotateX · 3D depth</p>
</div>
</div> <div class="ta-14">
<div class="ta-14__stage">
<p class="ta-14__eyebrow">Into the</p>
<div class="ta-14__scene">
<h2 class="ta-14__text">VOID</h2>
</div>
<p class="ta-14__sub">perspective · rotateX · 3D depth</p>
</div>
</div>.ta-14, .ta-14 *, .ta-14 *::before, .ta-14 *::after {
margin: 0; padding: 0; box-sizing: border-box;
}
.ta-14 ::selection { background: #4f46e5; color: #fff; }
.ta-14 {
--bg: radial-gradient(ellipse at center, #0d0d2e 0%, #050510 100%);
min-height: 100vh;
background: var(--bg);
display: flex;
align-items: center;
justify-content: center;
padding: 2rem;
font-family: 'Syne', 'Helvetica Neue', sans-serif;
overflow: hidden;
}
.ta-14__stage { text-align: center; }
.ta-14__eyebrow {
font-size: 0.72rem;
color: #3730a3;
letter-spacing: 0.3em;
text-transform: uppercase;
margin-bottom: 0.3rem;
}
.ta-14__scene {
perspective: 400px;
display: inline-block;
}
.ta-14__text {
font-size: clamp(3.5rem, 10vw, 6rem);
font-weight: 900;
letter-spacing: 0.1em;
background-image: linear-gradient(0deg, #4f46e5, #a78bfa, #c4b5fd, #e0e7ff, #a78bfa, #4f46e5);
-webkit-background-clip: text;
background-clip: text;
color: transparent;
animation: ta-14-spin 6s linear infinite;
transform-origin: center center;
display: block;
}
@keyframes ta-14-spin {
from { transform: rotateX(0deg); }
to { transform: rotateX(360deg); }
}
.ta-14__sub {
font-size: 0.65rem;
color: #1e1b4b;
margin-top: 1rem;
letter-spacing: 0.1em;
font-family: 'Courier New', monospace;
}
@media (prefers-reduced-motion: reduce) {
.ta-14__text { animation: none; transform: rotateX(0deg); color: #a78bfa; }
} .ta-14, .ta-14 *, .ta-14 *::before, .ta-14 *::after {
margin: 0; padding: 0; box-sizing: border-box;
}
.ta-14 ::selection { background: #4f46e5; color: #fff; }
.ta-14 {
--bg: radial-gradient(ellipse at center, #0d0d2e 0%, #050510 100%);
min-height: 100vh;
background: var(--bg);
display: flex;
align-items: center;
justify-content: center;
padding: 2rem;
font-family: 'Syne', 'Helvetica Neue', sans-serif;
overflow: hidden;
}
.ta-14__stage { text-align: center; }
.ta-14__eyebrow {
font-size: 0.72rem;
color: #3730a3;
letter-spacing: 0.3em;
text-transform: uppercase;
margin-bottom: 0.3rem;
}
.ta-14__scene {
perspective: 400px;
display: inline-block;
}
.ta-14__text {
font-size: clamp(3.5rem, 10vw, 6rem);
font-weight: 900;
letter-spacing: 0.1em;
background-image: linear-gradient(0deg, #4f46e5, #a78bfa, #c4b5fd, #e0e7ff, #a78bfa, #4f46e5);
-webkit-background-clip: text;
background-clip: text;
color: transparent;
animation: ta-14-spin 6s linear infinite;
transform-origin: center center;
display: block;
}
@keyframes ta-14-spin {
from { transform: rotateX(0deg); }
to { transform: rotateX(360deg); }
}
.ta-14__sub {
font-size: 0.65rem;
color: #1e1b4b;
margin-top: 1rem;
letter-spacing: 0.1em;
font-family: 'Courier New', monospace;
}
@media (prefers-reduced-motion: reduce) {
.ta-14__text { animation: none; transform: rotateX(0deg); color: #a78bfa; }
}How this works
A perspective: 400px on the parent creates a vanishing-point depth context. The text element itself uses transform-origin: center center and animates with rotateX() through 360deg. As the rotation progresses past 90° the text faces away, making it invisible if backface-visibility: hidden is applied — this creates a flip effect. Without that property, the text is visible mirrored on the back, giving a full-rotation barrel-roll feel.
The perspective depth causes near keyframes (0–90°, 270–360°) to appear larger and close, while the 180° position appears smaller and distant, simulating true 3D depth. The animation-timing-function: linear keeps the rotation constant speed, while a stepped or eased version gives a snapping tick through each quarter-turn for a more mechanical effect.
Customize
- Change the rotation axis to
rotateY()for a horizontal turntable spin instead of a tumbling barrel roll. - Lower the perspective to
200pxfor extreme forced-perspective distortion, or raise to1000pxfor an almost-flat rotation that feels like 2D. - Pause rotation on hover using
.ta-14:hover .ta-14__text { animation-play-state: paused; }to allow users to stop the spin at a chosen position. - Add a
background: linear-gradient()on the text that changes colour as it faces different directions, usingrotateXand a gradient perpendicular to the axis. - Combine
rotateXwith a slowrotateZ(5deg)orbit to create an unstable tumbling asteroid motion.
Watch out for
- Perspective only creates depth for elements with 3D transforms — the property must be on a direct parent, not a grandparent, unless
transform-style: preserve-3dis threaded through. - Setting
backface-visibility: hiddencauses the element to disappear for 180° of each rotation cycle — intentional for flips but undesirable for continuous spins. - Anti-aliasing artifacts can appear on rotated text in Safari at certain angles; adding a 1px transparent border or
outline: 1px solid transparentoften eliminates the jagging.
Browser support
| Chrome | Safari | Firefox | Edge |
|---|---|---|---|
| 36+ | 9+ | 16+ | 36+ |
CSS 3D transforms and perspective are universally supported in modern browsers. Always test in Safari for backface-visibility edge cases.