CSS Tips
3D Text Rotation Hover Effect
Create an impressive effect where two texts switch on hover using CSS 3D Transform.
Introduction
A hover effect where text rotates to reveal different text can be used in various scenarios such as language switching and menu items.
In this article, we'll show you how to implement a hover effect where text rotates along the X-axis using CSS 3D Transform.
Final Demo
Hover over the text below. The English text rotates up and disappears while the Japanese text appears.
<div class="demo-rotate-container">
<div class="demo-rotate-wrapper">
<span class="demo-rotate-text demo-rotate-text--front">delcano</span>
<span class="demo-rotate-text demo-rotate-text--back">デルカノ</span>
</div>
</div>
.demo-rotate-container {
display: flex;
justify-content: center;
align-items: center;
padding: 2rem 0;
}
.demo-rotate-wrapper {
width: 12rem;
height: 5rem;
position: relative;
cursor: pointer;
}
.demo-rotate-text {
display: grid;
place-items: center;
position: absolute;
inset: 0;
font-size: 2rem;
font-weight: 700;
transform-style: preserve-3d;
transition: rotate 0.4s ease;
transform-origin: center 50% -1.5rem;
color: #667eea;
user-select: none;
}
.demo-rotate-text--front {
rotate: x 0deg;
}
.demo-rotate-text--back {
color: #764ba2;
rotate: x -90deg;
}
.demo-rotate-wrapper:hover .demo-rotate-text--front {
rotate: x 90deg;
}
.demo-rotate-wrapper:hover .demo-rotate-text--back {
rotate: x 0deg;
}
How It Works
This effect is achieved by stacking two texts on top of each other and rotating each along the X-axis on hover.
The key points are:
1. **Stack two texts**
Position two texts at the same location using absolute positioning, and rotate one by -90 degrees initially to hide it.
2. **Z-axis offset with transform-origin**
Using transform-origin: center 50% -1.5rem sets a Z-axis offset, giving the text depth during rotation and preventing clipping.
3. **Concise syntax with rotate property**
The new CSS rotate property allows axis specification like rotate: x 90deg for cleaner code.
HTML Code
<div class="rotate-wrapper">
<span class="rotate-text rotate-text--front">delcano</span>
<span class="rotate-text rotate-text--back">デルカノ</span>
</div>
CSS Code
.rotate-wrapper {
width: 12rem;
height: 5rem;
position: relative;
cursor: pointer;
}
.rotate-text {
display: grid;
place-items: center;
position: absolute;
inset: 0;
font-size: 2rem;
font-weight: 700;
transform-style: preserve-3d;
transition: rotate 0.4s ease;
transform-origin: center 50% -1.5rem;
user-select: none;
}
.rotate-text--front {
color: #667eea;
rotate: x 0deg;
}
.rotate-text--back {
color: #764ba2;
rotate: x -90deg;
}
.rotate-wrapper:hover .rotate-text--front {
rotate: x 90deg;
}
.rotate-wrapper:hover .rotate-text--back {
rotate: x 0deg;
}
Role of Each Property
transform-origin Z-axis Offset
transform-origin: center 50% -1.5rem sets a Z-axis offset. This gives the text depth during rotation and prevents clipping.
rotate Property
Uses the new CSS rotate property. You can specify the axis like rotate: x 90deg. More concise than using transform.
transform-style: preserve-3d
Preserves 3D transformations of child elements. Without this, child elements are rendered flat.
inset: 0
A shorthand that sets top, right, bottom, left all to 0. Makes elements overlap at the same size as the parent.
place-items: center
A shorthand property that centers content both vertically and horizontally within a Grid container.
user-select: none
Disables text selection. Prevents accidental text selection during hover interactions.
Use Cases
This technique can be used in various scenarios.
**Language Switching**
Perfect for switching between languages like in the demo.
**Price Display**
Create an effect switching between regular and sale prices on hover.
**Navigation Menu**
Use it for switching between icons and text in menu items.
**Button Labels**
Apply it for multilingual support like "Read More" → "詳細を見る".
Summary
Using CSS 3D Transform, you can create an impressive hover effect where text rotates along the X-axis to switch.
The key is proper configuration of transform-origin and backface-visibility. Since it's achieved with CSS alone without JavaScript, it's lightweight and performs well.
Try incorporating this into language switching and interactive UIs.