25 CSS Text Animations 10 / 25

CSS 3D Text Flip Animation

Words rotate in 3D on the Y-axis using CSS perspective and backface-visibility to flip between two text faces like a rotating sign.

Pure CSS MIT licensed
Live Demo Open in tab
Open in playground

The code

<div class="ta-10">
  <div class="ta-10__stage">
    <p class="ta-10__label">Rotating between</p>
    <div class="ta-10__scene">
      <div class="ta-10__flipper">
        <div class="ta-10__face ta-10__face--front">Design</div>
        <div class="ta-10__face ta-10__face--back">Motion</div>
      </div>
    </div>
    <p class="ta-10__sub">perspective · rotateY · backface-visibility</p>
  </div>
</div>
.ta-10, .ta-10 *, .ta-10 *::before, .ta-10 *::after {
  margin: 0; padding: 0; box-sizing: border-box;
}
.ta-10 ::selection { background: #0f766e; color: #fff; }

.ta-10 {
  --bg: #05120f;
  --teal: #2dd4bf;
  --gold: #fbbf24;
  min-height: 100vh;
  background: var(--bg);
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 2rem;
  font-family: 'Syne', 'Helvetica Neue', sans-serif;
}

.ta-10__stage { text-align: center; }

.ta-10__label {
  font-size: 0.72rem;
  color: #1f4040;
  letter-spacing: 0.15em;
  text-transform: uppercase;
  margin-bottom: 0.5rem;
}

.ta-10__scene {
  perspective: 600px;
  display: inline-block;
  height: clamp(3rem, 9vw, 5.5rem);
  overflow: visible;
}

.ta-10__flipper {
  position: relative;
  transform-style: preserve-3d;
  animation: ta-10-flip 4s ease-in-out infinite;
  height: 100%;
  display: flex;
  align-items: center;
}

.ta-10__face {
  font-size: clamp(2.5rem, 8vw, 5rem);
  font-weight: 900;
  position: absolute;
  width: 100%;
  text-align: center;
  -webkit-backface-visibility: hidden;
  backface-visibility: hidden;
  letter-spacing: -0.02em;
  white-space: nowrap;
}

.ta-10__face--front { color: var(--teal); }
.ta-10__face--back  { color: var(--gold); transform: rotateY(180deg); }

.ta-10__sub {
  font-size: 0.65rem;
  color: #1a3030;
  margin-top: 1rem;
  letter-spacing: 0.08em;
  font-family: 'Courier New', monospace;
}

@keyframes ta-10-flip {
  0%   { transform: rotateY(0deg); }
  35%  { transform: rotateY(0deg); }
  50%  { transform: rotateY(-180deg); }
  85%  { transform: rotateY(-180deg); }
  100% { transform: rotateY(-360deg); }
}

@media (prefers-reduced-motion: reduce) {
  .ta-10__flipper { animation: none; }
  .ta-10__face--back { display: none; }
}

How this works

The flip container establishes a 3D rendering context with perspective: 600px on the parent and transform-style: preserve-3d on the flipping element. Two text faces — front and back — are both position: absolute and full-size, with the back face pre-rotated rotateY(180deg) so it starts facing away. backface-visibility: hidden on each face ensures only the forward-facing surface is visible at any rotation angle.

The ta-10-flip keyframe rotates the container from 0deg to -180deg then continues to -360deg, completing a full revolution. As the rotation passes 90° the front face disappears and the back face becomes visible, creating the card-flip illusion. Looping the animation with a hold pause (0–40% static, 50–60% flipping, 60–100% static on new face) makes each word linger before the next flip.

Customize

  • Change the rotation axis from Y to X using rotateX() for a top-to-bottom vertical page-turn effect instead of a horizontal spin.
  • Adjust the perspective value — lower values like 200px create an extreme fisheye distortion, while 1200px produces an almost-flat flip for subtle transitions.
  • Add a coloured edge illusion using border or box-shadow on the container that stays visible during the rotation, simulating card thickness.
  • Stack multiple flip containers with staggered delays to cycle through a list of words in a slot-machine or rotating headline module.
  • Replace text with icon SVGs or images on each face to create a flipping card reveal for portfolio thumbnails or feature highlights.

Watch out for

  • transform-style: preserve-3d must be on the direct parent of the rotating element — it does not cascade down through extra wrapper divs without being re-declared.
  • Safari occasionally ignores backface-visibility: hidden on certain hardware; adding -webkit-backface-visibility: hidden resolves the ghost-image issue in older Safari.
  • Mixing overflow: hidden or border-radius on a preserve-3d ancestor collapses the 3D context in Chrome and Safari — use a wrapper outside the 3D layer for clipping.

Browser support

ChromeSafariFirefoxEdge
36+ 9+ 16+ 36+

preserve-3d is well supported; always add -webkit-backface-visibility for Safari compatibility on the hidden faces.

Search CodeFronts

Loading…