CSS 48 💻 transform rotateX, rotateY and rotateZ
48. transform rotateX, rotateY, and rotateZ
These three functions are the individual axis rotations in CSS 3D transforms. Each one rotates an element around a specific axis: X (horizontal), Y (vertical), or Z (depth).
Overview of Functions
| Function | Axis | Equivalent | Visual Effect |
|---|---|---|---|
rotateX() | Horizontal | rotate3d(1, 0, 0, angle) | Tilts forward/backward |
rotateY() | Vertical | rotate3d(0, 1, 0, angle) | Turns left/right |
rotateZ() | Depth | rotate3d(0, 0, 1, angle) | Spins in place (2D) |
Understanding the Axes
Y (vertical)
↑
│
│
│
└──────────→ X (horizontal)
/
/
↙
Z (depth, toward viewer)
| Axis | Direction | Rotation Effect |
|---|---|---|
| X | Horizontal (left–right) | Tilts top toward/away from viewer |
| Y | Vertical (up–down) | Turns left/right (like a door) |
| Z | Depth (toward viewer) | Spins in the 2D plane |
1. rotateX()
Rotates an element around the X-axis (horizontal). The top and bottom move toward or away from the viewer.
.rotateX {
transform: rotateX(45deg);
}
| Angle | Effect |
|---|---|
rotateX(45deg) | Top tilts away, bottom tilts toward viewer |
rotateX(-45deg) | Top tilts toward, bottom tilts away |
rotateX(90deg) | Element becomes a flat line (edge-on) |
rotateX(180deg) | Element is flipped upside down |
Equivalent: rotate3d(1, 0, 0, 45deg)
Use cases:
- Flipping cards vertically
- Creating a “flipboard” effect
- 3D menus that open upward/downward
2. rotateY()
Rotates an element around the Y-axis (vertical). The left and right sides move toward or away from the viewer.
.rotateY {
transform: rotateY(45deg);
}
| Angle | Effect |
|---|---|
rotateY(45deg) | Right side goes away, left comes forward |
rotateY(-45deg) | Left side goes away, right comes forward |
rotateY(90deg) | Element becomes a flat line (edge-on) |
rotateY(180deg) | Element is flipped (mirror image) |
Equivalent: rotate3d(0, 1, 0, 45deg)
Use cases:
- Card flip animations (horizontal)
- Carousels
- Book page turns
- 3D product previews
3. rotateZ()
Rotates an element around the Z-axis (depth). This is the same as the 2D rotate() function.
.rotateZ {
transform: rotateZ(45deg);
}
| Angle | Effect |
|---|---|
rotateZ(45deg) | 45° clockwise (in the 2D plane) |
rotateZ(-45deg) | 45° counter-clockwise |
rotateZ(180deg) | Upside down (2D) |
Equivalent: rotate3d(0, 0, 1, 45deg) = rotate(45deg)
Use cases:
- Spinning icons
- Rotating badges
- 2D rotations in 3D contexts
Complete Example
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>rotateX, rotateY, and rotateZ</title>
<style>
*, *::before, *::after {
box-sizing: border-box;
}
body {
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
padding: 20px;
background: #f8f9fa;
color: #333;
max-width: 1200px;
margin: 0 auto;
line-height: 1.6;
}
h1 {
color: #007bff;
border-bottom: 3px solid #007bff;
padding-bottom: 10px;
}
h2 {
color: #28a745;
border-left: 4px solid #28a745;
padding-left: 15px;
margin-top: 30px;
}
h3 {
color: #333;
margin-top: 20px;
}
section {
background: white;
padding: 20px;
border-radius: 8px;
box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1);
margin: 20px 0;
}
.code-block {
background: #1e1e1e;
color: #d4d4d4;
padding: 15px;
border-radius: 8px;
overflow-x: auto;
font-family: 'Courier New', monospace;
font-size: 0.9rem;
line-height: 1.8;
margin: 10px 0;
}
.reference-table {
width: 100%;
border-collapse: collapse;
margin: 15px 0;
}
.reference-table th,
.reference-table td {
padding: 10px;
border: 1px solid #ddd;
text-align: left;
}
.reference-table th {
background: #007bff;
color: white;
}
.reference-table tr:nth-child(even) {
background: #f8f9fa;
}
.note {
font-size: 0.9rem;
color: #6c757d;
margin-top: 5px;
}
.highlight {
background: #ffc107;
color: #333;
padding: 2px 6px;
border-radius: 4px;
font-weight: bold;
}
/* ====== DEMO AREA ====== */
.demo-area {
display: flex;
flex-wrap: wrap;
gap: 40px;
justify-content: center;
align-items: center;
padding: 50px 20px;
background: #e9ecef;
border-radius: 8px;
margin: 15px 0;
min-height: 350px;
perspective: 800px;
}
.box {
width: 150px;
height: 150px;
background: linear-gradient(135deg, #007bff, #6c5ce7);
color: white;
display: flex;
align-items: center;
justify-content: center;
font-weight: bold;
font-size: 0.9rem;
border-radius: 12px;
transition: transform 1s;
cursor: pointer;
text-align: center;
padding: 10px;
box-shadow: 0 4px 15px rgba(0, 0, 0, 0.2);
transform-style: preserve-3d;
}
.box:hover {
box-shadow: 0 8px 30px rgba(0, 123, 255, 0.4);
}
/* Individual rotations */
.rotateX {
transform: rotateX(45deg);
}
.rotateX:hover {
transform: rotateX(90deg);
}
.rotateY {
transform: rotateY(45deg);
}
.rotateY:hover {
transform: rotateY(90deg);
}
.rotateZ {
transform: rotateZ(45deg);
}
.rotateZ:hover {
transform: rotateZ(90deg);
}
/* Angle comparisons */
.rotate-x-30 { transform: rotateX(30deg); }
.rotate-x-60 { transform: rotateX(60deg); }
.rotate-x-90 { transform: rotateX(90deg); }
.rotate-x-neg { transform: rotateX(-45deg); }
.rotate-y-30 { transform: rotateY(30deg); }
.rotate-y-60 { transform: rotateY(60deg); }
.rotate-y-90 { transform: rotateY(90deg); }
.rotate-y-neg { transform: rotateY(-45deg); }
.rotate-z-30 { transform: rotateZ(30deg); }
.rotate-z-90 { transform: rotateZ(90deg); }
.rotate-z-180 { transform: rotateZ(180deg); }
.rotate-z-neg { transform: rotateZ(-45deg); }
/* ====== AXIS VISUALIZATION ====== */
.axis-viz {
display: flex;
flex-wrap: wrap;
gap: 30px;
justify-content: center;
margin: 20px 0;
}
.axis-card {
text-align: center;
padding: 20px;
background: white;
border: 2px solid #ddd;
border-radius: 12px;
width: 200px;
transition: all 0.3s;
}
.axis-card:hover {
border-color: #007bff;
box-shadow: 0 4px 15px rgba(0, 123, 255, 0.15);
}
.axis-card .axis-icon {
font-size: 3rem;
margin-bottom: 10px;
}
.axis-card h4 {
margin: 5px 0;
color: #007bff;
}
.axis-card p {
font-size: 0.85rem;
color: #6c757d;
margin: 5px 0;
}
.axis-card code {
background: #e9ecef;
padding: 2px 6px;
border-radius: 4px;
font-family: 'Courier New', monospace;
font-size: 0.8rem;
color: #dc3545;
}
/* ====== PRACTICAL: CARD FLIP VERTICAL ====== */
.flip-container {
perspective: 1000px;
width: 250px;
height: 300px;
margin: 20px auto;
}
.flip-card {
width: 100%;
height: 100%;
position: relative;
transform-style: preserve-3d;
transition: transform 0.8s;
cursor: pointer;
}
.flip-container:hover .flip-card {
transform: rotateX(180deg);
}
.flip-front,
.flip-back {
position: absolute;
width: 100%;
height: 100%;
backface-visibility: hidden;
border-radius: 16px;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
padding: 20px;
text-align: center;
color: white;
font-weight: bold;
box-shadow: 0 10px 30px rgba(0, 0, 0, 0.2);
}
.flip-front {
background: linear-gradient(135deg, #007bff, #6c5ce7);
}
.flip-front .icon {
font-size: 3rem;
margin-bottom: 15px;
}
.flip-back {
background: linear-gradient(135deg, #28a745, #20c997);
transform: rotateX(180deg);
}
.flip-back h4 {
margin-top: 0;
}
.flip-back p {
font-size: 0.9rem;
font-weight: normal;
opacity: 0.95;
}
/* ====== PRACTICAL: 3D CUBE ====== */
.cube-scene {
width: 180px;
height: 180px;
perspective: 600px;
margin: 30px auto;
}
.cube {
width: 100%;
height: 100%;
position: relative;
transform-style: preserve-3d;
animation: spinCube 8s infinite linear;
}
@keyframes spinCube {
from { transform: rotateX(0) rotateY(0); }
to { transform: rotateX(360deg) rotateY(360deg); }
}
.cube .face {
position: absolute;
width: 180px;
height: 180px;
border: 2px solid rgba(0, 0, 0, 0.3);
display: flex;
align-items: center;
justify-content: center;
font-weight: bold;
color: white;
font-size: 1rem;
text-shadow: 0 2px 5px rgba(0,0,0,0.5);
border-radius: 8px;
}
.cube .front {
background: rgba(255, 0, 0, 0.8);
transform: translateZ(90px);
}
.cube .back {
background: rgba(0, 255, 0, 0.8);
transform: rotateY(180deg) translateZ(90px);
}
.cube .right {
background: rgba(0, 0, 255, 0.8);
transform: rotateY(90deg) translateZ(90px);
}
.cube .left {
background: rgba(255, 255, 0, 0.8);
transform: rotateY(-90deg) translateZ(90px);
}
.cube .top {
background: rgba(255, 0, 255, 0.8);
transform: rotateX(90deg) translateZ(90px);
}
.cube .bottom {
background: rgba(0, 255, 255, 0.8);
transform: rotateX(-90deg) translateZ(90px);
}
/* ====== TIPS ====== */
.tip-box {
padding: 15px;
border-radius: 8px;
margin: 10px 0;
border-left: 4px solid #007bff;
background: #f8f9fa;
}
.tip-box.success { border-left-color: #28a745; }
.tip-box.warning { border-left-color: #ffc107; }
.tip-box.danger { border-left-color: #dc3545; }
</style>
</head>
<body>
<h1>rotateX, rotateY, and rotateZ</h1>
<!-- ====== 1. BASIC ROTATIONS ====== -->
<section>
<h2>1. Basic Axis Rotations</h2>
<p>Hover over each box to see the rotation increase.</p>
<div class="demo-area">
<div class="box rotateX">rotateX(45deg)</div>
<div class="box rotateY">rotateY(45deg)</div>
<div class="box rotateZ">rotateZ(45deg)</div>
</div>
<p class="note"><strong>rotateX</strong> tilts forward/backward. <strong>rotateY</strong> turns left/right. <strong>rotateZ</strong> spins in place.</p>
<div class="code-block">
/* Rotate around X-axis (horizontal) */
.rotateX {
transform: rotateX(45deg);
}
/* Rotate around Y-axis (vertical) */
.rotateY {
transform: rotateY(45deg);
}
/* Rotate around Z-axis (depth) */
.rotateZ {
transform: rotateZ(45deg);
}
</div>
</section>
<!-- ====== 2. AXIS VISUALIZATION ====== -->
<section>
<h2>2. Understanding the Axes</h2>
<div class="axis-viz">
<div class="axis-card">
<div class="axis-icon">↔️</div>
<h4>X-Axis</h4>
<p>Horizontal (left–right)</p>
<code>rotateX(45deg)</code>
<p class="note">Tilts top toward/away from viewer</p>
</div>
<div class="axis-card">
<div class="axis-icon">↕️</div>
<h4>Y-Axis</h4>
<p>Vertical (up–down)</p>
<code>rotateY(45deg)</code>
<p class="note">Turns left/right like a door</p>
</div>
<div class="axis-card">
<div class="axis-icon">🔄</div>
<h4>Z-Axis</h4>
<p>Depth (toward viewer)</p>
<code>rotateZ(45deg)</code>
<p class="note">Spins in the 2D plane (like rotate())</p>
</div>
</div>
<div class="code-block">
/* These are equivalent */
rotateX(45deg) = rotate3d(1, 0, 0, 45deg)
rotateY(45deg) = rotate3d(0, 1, 0, 45deg)
rotateZ(45deg) = rotate3d(0, 0, 1, 45deg)
/* rotateZ() is the same as 2D rotate() */
rotateZ(45deg) = rotate(45deg)
</div>
</section>
<!-- ====== 3. ROTATEX ANGLES ====== -->
<section>
<h2>3. rotateX() Angle Comparison</h2>
<div class="demo-area">
<div class="box rotate-x-30">30°</div>
<div class="box rotate-x-60">60°</div>
<div class="box rotate-x-90">90°</div>
<div class="box rotate-x-neg">-45°</div>
</div>
<div class="code-block">
.rotate-x-30 { transform: rotateX(30deg); }
.rotate-x-60 { transform: rotateX(60deg); }
.rotate-x-90 { transform: rotateX(90deg); } /* Edge-on */
.rotate-x-neg { transform: rotateX(-45deg); } /* Opposite direction */
</div>
<p class="note">At <code>rotateX(90deg)</code>, the element becomes a flat line (edge-on to the viewer).</p>
</section>
<!-- ====== 4. ROTATEY ANGLES ====== -->
<section>
<h2>4. rotateY() Angle Comparison</h2>
<div class="demo-area">
<div class="box rotate-y-30">30°</div>
<div class="box rotate-y-60">60°</div>
<div class="box rotate-y-90">90°</div>
<div class="box rotate-y-neg">-45°</div>
</div>
<div class="code-block">
.rotate-y-30 { transform: rotateY(30deg); }
.rotate-y-60 { transform: rotateY(60deg); }
.rotate-y-90 { transform: rotateY(90deg); } /* Edge-on */
.rotate-y-neg { transform: rotateY(-45deg); } /* Opposite direction */
</div>
<p class="note">At <code>rotateY(90deg)</code>, the element becomes a flat line (edge-on to the viewer).</p>
</section>
<!-- ====== 5. ROTATEZ ANGLES ====== -->
<section>
<h2>5. rotateZ() Angle Comparison</h2>
<div class="demo-area">
<div class="box rotate-z-30">30°</div>
<div class="box rotate-z-90">90°</div>
<div class="box rotate-z-180">180°</div>
<div class="box rotate-z-neg">-45°</div>
</div>
<div class="code-block">
.rotate-z-30 { transform: rotateZ(30deg); }
.rotate-z-90 { transform: rotateZ(90deg); }
.rotate-z-180 { transform: rotateZ(180deg); } /* Upside down */
.rotate-z-neg { transform: rotateZ(-45deg); }
</div>
<p class="note"><code>rotateZ()</code> is a 2D rotation — it doesn't create depth.</p>
</section>
<!-- ====== 6. PRACTICAL: VERTICAL CARD FLIP ====== -->
<section>
<h2>6. Practical Example: Vertical Card Flip</h2>
<p>Hover over the card to flip it vertically using <code>rotateX()</code>.</p>
<div class="flip-container">
<div class="flip-card">
<div class="flip-front">
<div class="icon">🎴</div>
<h3 style="margin: 0;">Vertical Flip</h3>
<p style="font-weight: normal; font-size: 0.9rem;">Hover to flip</p>
</div>
<div class="flip-back">
<h4>✨ Back Side</h4>
<p>This card uses <code>rotateX(180deg)</code> to flip vertically.</p>
</div>
</div>
</div>
<div class="code-block">
.flip-container {
perspective: 1000px;
}
.flip-card {
transform-style: preserve-3d;
transition: transform 0.8s;
}
.flip-container:hover .flip-card {
transform: rotateX(180deg); /* Vertical flip */
}
.flip-back {
transform: rotateX(180deg);
backface-visibility: hidden;
}
</div>
</section>
<!-- ====== 7. PRACTICAL: 3D CUBE ====== -->
<section>
<h2>7. Practical Example: 3D Cube</h2>
<p>A rotating cube using <code>rotateX</code> and <code>rotateY</code> together.</p>
<div class="cube-scene">
<div class="cube">
<div class="face front">Front</div>
<div class="face back">Back</div>
<div class="face right">Right</div>
<div class="face left">Left</div>
<div class="face top">Top</div>
<div class="face bottom">Bottom</div>
</div>
</div>
<div class="code-block">
.cube {
transform-style: preserve-3d;
animation: spinCube 8s infinite linear;
}
@keyframes spinCube {
from { transform: rotateX(0) rotateY(0); }
to { transform: rotateX(360deg) rotateY(360deg); }
}
/* Each face positioned in 3D space */
.front { transform: translateZ(90px); }
.back { transform: rotateY(180deg) translateZ(90px); }
.right { transform: rotateY(90deg) translateZ(90px); }
.left { transform: rotateY(-90deg) translateZ(90px); }
.top { transform: rotateX(90deg) translateZ(90px); }
.bottom { transform: rotateX(-90deg) translateZ(90px); }
</div>
</section>
<!-- ====== 8. REFERENCE TABLES ====== -->
<section>
<h2>8. Reference Tables</h2>
<h3>Axis Rotation Functions</h3>
<table class="reference-table">
<tr>
<th>Function</th>
<th>Axis</th>
<th>Equivalent</th>
<th>Effect</th>
</tr>
<tr>
<td><code>rotateX()</code></td>
<td>Horizontal</td>
<td><code>rotate3d(1, 0, 0, angle)</code></td>
<td>Tilts forward/backward</td>
</tr>
<tr>
<td><code>rotateY()</code></td>
<td>Vertical</td>
<td><code>rotate3d(0, 1, 0, angle)</code></td>
<td>Turns left/right</td>
</tr>
<tr>
<td><code>rotateZ()</code></td>
<td>Depth</td>
<td><code>rotate3d(0, 0, 1, angle)</code></td>
<td>Spins in 2D plane</td>
</tr>
</table>
<h3>Angle Effects</h3>
<table class="reference-table">
<tr>
<th>Angle</th>
<th>Effect</th>
</tr>
<tr>
<td><code>0deg</code></td>
<td>No rotation</td>
</tr>
<tr>
<td><code>45deg</code></td>
<td>Moderate tilt/turn</td>
</tr>
<tr>
<td><code>90deg</code></td>
<td>Edge-on (flat line)</td>
</tr>
<tr>
<td><code>180deg</code></td>
<td>Flipped (upside down / mirror)</td>
</tr>
<tr>
<td><code>360deg</code></td>
<td>Full rotation (same as 0°)</td>
</tr>
<tr>
<td><code>-45deg</code></td>
<td>Opposite direction</td>
</tr>
</table>
<h3>Related Properties</h3>
<table class="reference-table">
<tr>
<th>Property</th>
<th>Description</th>
</tr>
<tr>
<td><code>perspective</code></td>
<td>Distance from viewer (on parent)</td>
</tr>
<tr>
<td><code>transform-style</code></td>
<td><code>preserve-3d</code> for 3D children</td>
</tr>
<tr>
<td><code>backface-visibility</code></td>
<td>Hide back face of 3D element</td>
</tr>
<tr>
<td><code>perspective-origin</code></td>
<td>Vanishing point (default: center)</td>
</tr>
</table>
</section>
<!-- ====== 9. BEST PRACTICES ====== -->
<section>
<h2>9. Best Practices</h2>
<div style="background: #d4edda; padding: 20px; border-radius: 8px; border-left: 4px solid #28a745;">
<h3 style="margin-top: 0; color: #155724;">✅ Do This:</h3>
<ul>
<li>Use <code>rotateX()</code> for vertical flips (cards, panels)</li>
<li>Use <code>rotateY()</code> for horizontal flips (carousels, book pages)</li>
<li>Use <code>rotateZ()</code> for 2D spinning (icons, badges)</li>
<li>Apply <code>perspective</code> to the parent for 3D depth</li>
<li>Use <code>transform-style: preserve-3d</code> on the 3D container</li>
<li>Use <code>backface-visibility: hidden</code> for card flips</li>
<li>Test on different devices and browsers</li>
</ul>
</div>
<div style="background: #f8d7da; padding: 20px; border-radius: 8px; border-left: 4px solid #dc3545; margin-top: 15px;">
<h3 style="margin-top: 0; color: #721c24;">❌ Don't Do This:</h3>
<ul>
<li>Don't apply <code>perspective</code> to the element being rotated (apply to parent)</li>
<li>Don't forget <code>transform-style: preserve-3d</code> for 3D children</li>
<li>Don't overuse 3D rotations — they can cause motion sickness</li>
<li>Don't use <code>rotateX(90deg)</code> or <code>rotateY(90deg)</code> for visible content (it becomes edge-on)</li>
<li>Don't forget to respect <code>prefers-reduced-motion</code></li>
</ul>
</div>
<div class="code-block">
/* Accessibility: respect reduced motion */
@media (prefers-reduced-motion: reduce) {
.box {
transition: none;
transform: none;
}
.cube {
animation: none;
}
}
</div>
</section>
</body>
</html>
Quick Reference
| Function | Axis | Equivalent | Effect |
|---|---|---|---|
rotateX() | Horizontal | rotate3d(1, 0, 0, angle) | Tilts forward/backward |
rotateY() | Vertical | rotate3d(0, 1, 0, angle) | Turns left/right |
rotateZ() | Depth | rotate3d(0, 0, 1, angle) | Spins in 2D plane |
Angle Effects
| Angle | Effect |
|---|---|
0deg | No rotation |
45deg | Moderate tilt/turn |
90deg | Edge-on (flat line) |
180deg | Flipped (upside down / mirror) |
360deg | Full rotation (same as 0°) |
-45deg | Opposite direction |
Use Cases
| Function | Best For |
|---|---|
rotateX() | Vertical card flips, flipboards, 3D menus |
rotateY() | Horizontal card flips, carousels, book pages |
rotateZ() | Spinning icons, rotating badges, 2D rotations |
Best Practices
✅ Do This:
/* Vertical card flip */
.card-scene:hover .card {
transform: rotateX(180deg);
}
/* Horizontal card flip */
.card-scene:hover .card {
transform: rotateY(180deg);
}
/* 2D spin */
.icon:hover {
transform: rotateZ(360deg);
}
/* 3D cube with both axes */
.cube {
animation: spin 8s infinite;
transform-style: preserve-3d;
}
@keyframes spin {
from { transform: rotateX(0) rotateY(0); }
to { transform: rotateX(360deg) rotateY(360deg); }
}
/* Respect reduced motion */
@media (prefers-reduced-motion: reduce) {
.card-scene:hover .card {
transform: none;
}
}
❌ Don’t Do This:
/* Don't apply perspective to the rotating element */
.box {
perspective: 600px; /* Wrong — apply to parent */
transform: rotateX(45deg);
}
/* Don't forget transform-style for 3D children */
.cube {
/* Missing transform-style: preserve-3d */
}
/* Don't use 90deg for visible content */
.box {
transform: rotateX(90deg); /* Becomes a flat line! */
}
Pro Tip: Think of the axes like this: rotateX is like a book cover opening (tilting top away from you), rotateY is like a door swinging (turning left/right), and rotateZ is like a clock hand spinning (2D rotation). Use rotateX(180deg) for vertical card flips, rotateY(180deg) for horizontal flips, and rotateZ() for simple spinning icons. Remember: at 90 degrees, the element becomes edge-on and appears as a flat line — so avoid using 90° for content that needs to remain visible!
Stop using slow, ad-bloated tool sites! 🤮
🔎 Search “KandZ Tools” on Google to use many professional utilities for free.
KandZ.me is the ultimate minimalist hub for:
✅ Finance (Mortgage, Interest, Inflation)
✅ Tech (Base64, JSON, Dev Suite, IP)
✅ Health (BMI, BMR, TDEE)
✅ Productivity (Timer, Workspace, QR)
⚡️ Fast & Private
🔒 No data leaves your device
💎 100% Free
🔗 Use it now: https://tools.kandz.me
🔖 Bookmark it—you’ll need it later!