CSS Transforms Guide
A complete reference for CSS transforms. Learn how to translate, rotate, scale, and skew elements in 2D and 3D space. Transforms are GPU-accelerated for smooth animations.
Translate
Move elements along the X, Y, or Z axis without affecting document flow.
translateX() & translateY()
/* Move horizontally */
.element {
transform: translateX(50px); /* Move right 50px */
transform: translateX(-50px); /* Move left 50px */
transform: translateX(50%); /* Move right 50% of element width */
}
/* Move vertically */
.element {
transform: translateY(50px); /* Move down 50px */
transform: translateY(-50px); /* Move up 50px */
transform: translateY(50%); /* Move down 50% of element height */
}
Hover over each box to see the transform:
translate() Shorthand
/* Move both axes at once */
.element {
transform: translate(50px, 30px); /* X, Y */
transform: translate(50px); /* X only, Y = 0 */
transform: translate(10%, 20%); /* Percentage values */
}
/* Common centering pattern */
.centered {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
}
translateZ() & translate3d()
/* Move along Z axis (requires perspective) */
.element {
transform: translateZ(50px); /* Move toward viewer */
transform: translateZ(-50px); /* Move away from viewer */
}
/* 3D translate shorthand */
.element {
transform: translate3d(50px, 30px, 20px); /* X, Y, Z */
}
/* Hardware acceleration trick */
.element {
transform: translateZ(0); /* Forces GPU layer */
/* or */
transform: translate3d(0, 0, 0);
}
Rotate
Rotate elements around the center point (or a custom origin).
rotate()
/* Basic rotation (2D, around Z axis) */
.element {
transform: rotate(45deg); /* Clockwise 45 degrees */
transform: rotate(-45deg); /* Counter-clockwise */
transform: rotate(0.25turn); /* Quarter turn (90deg) */
transform: rotate(1turn); /* Full rotation */
transform: rotate(100grad); /* Gradians (90deg) */
transform: rotate(1rad); /* Radians (~57.3deg) */
}
Hover over each box to see the transform:
3D Rotation
/* Rotate around specific axis */
.element {
transform: rotateX(45deg); /* Rotate around X (horizontal) axis */
transform: rotateY(45deg); /* Rotate around Y (vertical) axis */
transform: rotateZ(45deg); /* Same as rotate() */
}
/* Rotate around custom axis */
.element {
/* rotate3d(x, y, z, angle) - x,y,z define axis vector */
transform: rotate3d(1, 0, 0, 45deg); /* Same as rotateX */
transform: rotate3d(0, 1, 0, 45deg); /* Same as rotateY */
transform: rotate3d(1, 1, 0, 45deg); /* Diagonal axis */
transform: rotate3d(1, 1, 1, 45deg); /* 3D diagonal */
}
Hover to see 3D rotations (requires perspective):
Scale
Resize elements larger or smaller from their center point.
scale(), scaleX(), scaleY()
/* Uniform scaling */
.element {
transform: scale(1.5); /* 150% size */
transform: scale(0.5); /* 50% size */
transform: scale(2); /* Double size */
}
/* Non-uniform scaling */
.element {
transform: scale(1.5, 0.5); /* X: 150%, Y: 50% */
transform: scaleX(1.5); /* Width only */
transform: scaleY(1.5); /* Height only */
}
/* Flip/mirror */
.element {
transform: scale(-1, 1); /* Flip horizontally */
transform: scale(1, -1); /* Flip vertically */
transform: scale(-1, -1); /* Flip both (rotate 180) */
transform: scaleX(-1); /* Flip horizontally */
}
Hover over each box to see the transform:
scale3d() & scaleZ()
/* 3D scaling */
.element {
transform: scale3d(1.5, 1.5, 1.5); /* X, Y, Z */
transform: scaleZ(2); /* Z axis only */
}
/* scaleZ only visible with 3D rotation */
.element {
transform: scaleZ(2) rotateX(45deg);
}
Skew
Distort elements by tilting them along the X or Y axis.
skewX(), skewY(), skew()
/* Skew along X axis (horizontal tilt) */
.element {
transform: skewX(15deg);
transform: skewX(-15deg);
}
/* Skew along Y axis (vertical tilt) */
.element {
transform: skewY(15deg);
transform: skewY(-15deg);
}
/* Skew both axes */
.element {
transform: skew(15deg, 10deg); /* X, Y */
transform: skew(15deg); /* X only */
}
Hover over each box to see the transform:
Note: There is no skewZ() function. Skew is a 2D-only transformation.
Transform Origin
Set the point around which transforms occur. Default is center (50% 50%).
Keywords & Values
/* Keyword values */
.element {
transform-origin: center; /* Default: 50% 50% */
transform-origin: top; /* 50% 0 */
transform-origin: bottom; /* 50% 100% */
transform-origin: left; /* 0 50% */
transform-origin: right; /* 100% 50% */
transform-origin: top left; /* 0 0 */
transform-origin: top right; /* 100% 0 */
transform-origin: bottom left; /* 0 100% */
transform-origin: bottom right; /* 100% 100% */
}
/* Percentage values */
.element {
transform-origin: 25% 75%;
transform-origin: 0% 0%; /* Same as top left */
transform-origin: 100% 100%; /* Same as bottom right */
}
/* Length values */
.element {
transform-origin: 20px 30px;
transform-origin: 2rem 3rem;
}
/* 3D origin (X, Y, Z) */
.element {
transform-origin: center center 50px;
transform-origin: 50% 50% 100px;
}
Hover to see rotation from different origins:
Combining Transforms
Apply multiple transforms in a single declaration. Order matters!
Multiple Transform Functions
/* Space-separated list of transforms */
.element {
transform: translateX(50px) rotate(45deg);
transform: scale(1.2) rotate(45deg) translateY(20px);
transform: rotate(45deg) scale(1.5) skewX(10deg);
}
/* Order matters! These produce different results: */
.element-a {
transform: translateX(100px) rotate(45deg);
/* First move right, then rotate in place */
}
.element-b {
transform: rotate(45deg) translateX(100px);
/* First rotate, then move along rotated X axis */
}
Hover to see combined transforms:
matrix() & matrix3d()
/* 2D matrix - combines all 2D transforms */
/* matrix(a, b, c, d, tx, ty) */
.element {
/* Identity matrix (no transform) */
transform: matrix(1, 0, 0, 1, 0, 0);
/* Scale 2x horizontally */
transform: matrix(2, 0, 0, 1, 0, 0);
/* Translate 50px, 30px */
transform: matrix(1, 0, 0, 1, 50, 30);
}
/* 3D matrix - 16 values for full 3D transformation */
/* matrix3d(a1, b1, c1, d1, a2, b2, c2, d2, a3, b3, c3, d3, a4, b4, c4, d4) */
.element {
transform: matrix3d(
1, 0, 0, 0,
0, 1, 0, 0,
0, 0, 1, 0,
0, 0, 0, 1
);
}
Tip: Use individual transform functions for readability. matrix() is typically generated by JavaScript libraries or browser DevTools.
3D Transforms
Create three-dimensional transformations with perspective depth.
transform-style
/* Preserve 3D transformations on children */
.parent {
transform-style: flat; /* Default - children flattened */
transform-style: preserve-3d; /* Children maintain 3D position */
}
/* Required for nested 3D transforms */
.container {
perspective: 1000px;
}
.parent {
transform-style: preserve-3d;
transform: rotateY(45deg);
}
.child {
transform: rotateX(30deg); /* Visible in 3D space */
}
backface-visibility
/* Control visibility when rotated away */
.element {
backface-visibility: visible; /* Default - back is visible */
backface-visibility: hidden; /* Hide when facing away */
}
/* Essential for card flip effect */
.card-front,
.card-back {
backface-visibility: hidden;
}
.card-back {
transform: rotateY(180deg);
}
3D Card Flip Example
.flip-container {
perspective: 1000px;
}
.flip-card {
position: relative;
transform-style: preserve-3d;
transition: transform 0.6s ease;
}
.flip-container:hover .flip-card {
transform: rotateY(180deg);
}
.flip-front,
.flip-back {
position: absolute;
width: 100%;
height: 100%;
backface-visibility: hidden;
}
.flip-back {
transform: rotateY(180deg);
}
3D Cube Example
Perspective
Add depth to 3D transforms. Lower values = more dramatic effect.
perspective Property vs Function
/* As a property (on parent) - shared vanishing point */
.parent {
perspective: 500px; /* Distance from viewer */
}
.parent .child {
transform: rotateY(45deg); /* All children share perspective */
}
/* As a function (on element) - individual perspective */
.element {
transform: perspective(500px) rotateY(45deg);
}
/* Common values */
.element {
perspective: 100px; /* Very dramatic */
perspective: 500px; /* Moderate */
perspective: 1000px; /* Subtle */
perspective: none; /* No perspective */
}
perspective-origin
/* Set vanishing point position */
.element {
perspective: 500px;
perspective-origin: center; /* Default: 50% 50% */
perspective-origin: top; /* Look from above */
perspective-origin: bottom; /* Look from below */
perspective-origin: left; /* Look from left */
perspective-origin: right; /* Look from right */
perspective-origin: top left; /* Look from top-left */
perspective-origin: 25% 75%; /* Custom position */
}
Perspective Comparison
Hover to see the same rotation with different perspectives:
Practical Examples
Common real-world uses for CSS transforms.
Centering with Transform
/* Absolute centering */
.centered {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
}
/* Fixed modal centering */
.modal {
position: fixed;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
}
Hover Effects
/* Lift on hover */
.card {
transition: transform 0.3s ease;
}
.card:hover {
transform: translateY(-8px);
}
/* Grow on hover */
.button {
transition: transform 0.2s ease;
}
.button:hover {
transform: scale(1.05);
}
/* Combined lift and grow */
.interactive {
transition: transform 0.3s ease;
}
.interactive:hover {
transform: translateY(-4px) scale(1.02);
}
Image Zoom in Container
.image-container {
overflow: hidden;
}
.image-container img {
transition: transform 0.5s ease;
}
.image-container:hover img {
transform: scale(1.1);
}
Rotate Icon on Hover
.icon {
transition: transform 0.3s ease;
}
.button:hover .icon {
transform: rotate(90deg);
}
/* Full spin */
.button:hover .icon {
transform: rotate(360deg);
}
Slide-in Animation
@keyframes slideIn {
from {
transform: translateX(-100%);
opacity: 0;
}
to {
transform: translateX(0);
opacity: 1;
}
}
.slide-in {
animation: slideIn 0.5s ease forwards;
}
Performance Tips
Transforms are GPU-accelerated when used correctly.
GPU-Accelerated Properties
✅ Fast (Compositor)
These properties don't trigger layout or paint:
transformopacity
⚠️ Slow (Layout/Paint)
Avoid animating these properties:
width, heighttop, leftmargin, padding
Best Practices
/* ❌ Bad - animates layout properties */
.element {
left: 0;
transition: left 0.3s;
}
.element:hover {
left: 100px;
}
/* ✅ Good - uses transform */
.element {
transform: translateX(0);
transition: transform 0.3s;
}
.element:hover {
transform: translateX(100px);
}
/* ❌ Bad - animates width */
.element {
width: 100px;
transition: width 0.3s;
}
.element:hover {
width: 200px;
}
/* ✅ Good - uses scale */
.element {
transform: scaleX(1);
transition: transform 0.3s;
}
.element:hover {
transform: scaleX(2);
}
will-change Hint
/* Hint browser about upcoming changes */
.element {
will-change: transform;
}
/* Remove after animation if needed */
.element.animated {
will-change: auto;
}
/* ❌ Don't overuse */
* {
will-change: transform; /* Too broad */
}
Key Rule: Use transform and opacity for animations. They run on the compositor thread without triggering expensive layout recalculations.