CSS 2D Transforms: Translate, Rotate, Scale, and Skew
What Are CSS Transforms?
CSS transforms let you visually change an element's position, size, rotation, or shape without affecting the document flow. The original space the element occupies is preserved — other elements don't move.
.box {
transform: translateX(50px);
/* Box visually moves 50px right, but its original space remains */
}translate() — Moving Elements
translate() moves an element from its current position:
/* Move right 50px and down 20px */
transform: translate(50px, 20px);
/* Move only horizontally */
transform: translateX(100px); /* Right */
transform: translateX(-100px); /* Left */
/* Move only vertically */
transform: translateY(50px); /* Down */
transform: translateY(-50px); /* Up */
/* Percentage values (relative to element's own size) */
transform: translateX(50%); /* Half its own width */
transform: translate(-50%, -50%); /* Center trick */Centering with Translate
.centered {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
}This is one of the most reliable centering techniques in CSS.
rotate() — Spinning Elements
rotate() rotates an element around its center point:
/* Clockwise rotation */
transform: rotate(45deg);
/* Counter-clockwise */
transform: rotate(-45deg);
/* Full rotation */
transform: rotate(360deg);
/* Turn units */
transform: rotate(0.25turn); /* 90 degrees */
transform: rotate(0.5turn); /* 180 degrees */Practical Rotation
/* Tilted card effect */
.card:hover {
transform: rotate(2deg);
}
/* Arrow indicator */
.arrow-down {
transform: rotate(90deg);
}
/* Loading spinner */
@keyframes spin {
to { transform: rotate(360deg); }
}
.spinner {
animation: spin 1s linear infinite;
}scale() — Resizing Elements
scale() increases or decreases an element's size:
/* Scale both dimensions */
transform: scale(1.5); /* 150% size */
transform: scale(0.5); /* 50% size */
transform: scale(1); /* Normal (no change) */
/* Scale X and Y independently */
transform: scale(2, 1); /* Double width, normal height */
transform: scaleX(1.5); /* Only width */
transform: scaleY(0.8); /* Only height */
/* Flip */
transform: scaleX(-1); /* Horizontal flip */
transform: scaleY(-1); /* Vertical flip */
transform: scale(-1); /* Both axes flip */Practical Scale
/* Hover zoom effect */
.card:hover {
transform: scale(1.05);
}
/* Button press effect */
.button:active {
transform: scale(0.95);
}
/* Image zoom on hover */
.image-container {
overflow: hidden;
}
.image-container img {
transition: transform 0.3s ease;
}
.image-container img:hover {
transform: scale(1.1);
}skew() — Slanting Elements
skew() tilts an element along the X and/or Y axis:
/* Skew along X axis */
transform: skewX(15deg);
/* Skew along Y axis */
transform: skewY(10deg);
/* Both axes */
transform: skew(15deg, 5deg);Practical Skew
/* Parallelogram button */
.skewed-btn {
transform: skewX(-10deg);
padding: 0.75rem 2rem;
background: #3498db;
}
/* Fix text inside skewed element */
.skewed-btn span {
display: inline-block;
transform: skewX(10deg); /* Counter-skew the text */
}
/* Ribbon effect */
.ribbon {
transform: skewX(-15deg);
background: #e74c3c;
color: white;
padding: 0.5rem 2rem;
}Combining Multiple Transforms
Apply multiple transforms in a single declaration (they execute right to left):
/* Translate, then rotate, then scale */
transform: scale(1.1) rotate(5deg) translateY(-10px);
/* Order matters! */
transform: translateX(100px) rotate(45deg);
/* Different from: */
transform: rotate(45deg) translateX(100px);transform-origin
By default, transforms happen around the element's center. Change this with transform-origin:
/* Default: center */
transform-origin: center center;
/* Top-left corner */
transform-origin: top left;
/* Bottom-right corner */
transform-origin: bottom right;
/* Specific values */
transform-origin: 0 0; /* Same as top left */
transform-origin: 100% 100%; /* Same as bottom right */
transform-origin: 50px 30px; /* Specific point */Practical transform-origin
/* Door-opening effect (rotates from left edge) */
.door {
transform-origin: left center;
transition: transform 0.5s;
}
.door:hover {
transform: rotateY(-70deg);
}
/* Scale from top-left */
.tooltip {
transform-origin: top left;
transform: scale(0);
transition: transform 0.2s;
}
.tooltip.visible {
transform: scale(1);
}Transforms with Transitions
Transforms work beautifully with CSS transitions for smooth animations:
.card {
transition: transform 0.3s ease;
}
.card:hover {
transform: translateY(-8px) scale(1.02);
}
/* Button with multiple effects */
.btn {
transition: transform 0.2s ease, box-shadow 0.2s ease;
}
.btn:hover {
transform: translateY(-2px);
box-shadow: 0 4px 12px rgba(0,0,0,0.15);
}
.btn:active {
transform: translateY(0);
box-shadow: 0 1px 3px rgba(0,0,0,0.1);
}Performance Benefits
Transforms are GPU-accelerated and don't trigger layout recalculations, making them ideal for animations:
/* GOOD: GPU-accelerated, smooth */
transform: translateX(100px);
/* BAD: Triggers layout, can be janky */
margin-left: 100px;
left: 100px;Always prefer transform: translate() over changing position properties for animations.
Summary
CSS 2D transforms visually manipulate elements without affecting document flow. Use translate() for movement, rotate() for rotation, scale() for resizing, and skew() for slanting. Combine multiple transforms in one declaration, adjust the pivot point with transform-origin, and pair with transitions for smooth interactive effects. Transforms are GPU-accelerated, making them the most performant way to animate element position and size.