CSS Transform and Transitions
transform lets you move, rotate, scale, or skew an element without affecting the document layout. Other elements on the page don’t shift when you transform something.
transition makes those changes animate smoothly instead of snapping instantly.
@keyframes lets you define multi-step animations.
transform
translate()
Move an element from its current position. Positive translateX moves right; positive translateY moves down.
/* Move 200px to the right */
img {
transform: translateX(200px);
}
/* Move 200px to the left */
img {
transform: translateX(-200px);
}
/* Move 200px down */
img {
transform: translateY(200px);
}
/* Move 200px up */
img {
transform: translateY(-200px);
}
/* Move 50px right and 100px down */
img {
transform: translate(50px, 100px);
}
rotate()
Rotate an element clockwise. Use negative values to rotate counterclockwise.
.icon {
transform: rotate(45deg);
}
.flipped {
transform: rotate(-90deg);
}
scale()
Resize an element. scale(1) is normal size. scale(2) doubles it. scale(0.5) halves it.
/* Double the size */
img {
transform: scale(2);
}
/* Half the size */
img {
transform: scale(0.5);
}
/* Stretch only horizontally */
img {
transform: scaleX(3);
}
/* Shrink only vertically */
img {
transform: scaleY(0.5);
}
skew()
Tilt an element along the x or y axis.
.slant {
transform: skewX(10deg);
}
.skewed-both {
transform: skew(10deg, 5deg);
}
Chaining multiple transforms
List them space-separated in a single transform property. They are applied right to left.
.combined {
transform: translateX(20px) rotate(15deg) scale(1.1);
}
transform-origin
By default, transforms happen around the center of the element (50% 50%). Use transform-origin to change that point.
/* Rotate from the top-left corner instead of the center */
.rotate-from-top {
transform-origin: top left;
transform: rotate(45deg);
}
/* Scale from the bottom center */
.grow-up {
transform-origin: bottom center;
transform: scale(1.5);
}
transition
transition animates a CSS property change smoothly over time. Define the property to watch, the duration, and the timing curve.
.button {
background-color: #3b82f6;
transition: background-color 0.2s ease;
}
.button:hover {
background-color: #1d4ed8;
}
The shorthand order is: property duration timing-function delay.
Common timing functions:
ease: starts fast, slows down at the end (the default)linear: constant speed throughoutease-in: starts slow, ends fastease-out: starts fast, ends slowease-in-out: slow at both ends
You can transition multiple properties by separating them with commas.
.card {
transition: transform 0.2s ease, box-shadow 0.2s ease;
}
.card:hover {
transform: translateY(-4px);
box-shadow: 0 8px 24px rgba(0, 0, 0, 0.15);
}
Avoid transition: all in production. It watches every property, which can cause unexpected animations and hurt performance. List the specific properties instead.
@keyframes animations
For animations that run on load, loop, or have more than two states, use @keyframes.
Define the keyframes first, then apply the animation to an element.
@keyframes fade-in {
from {
opacity: 0;
transform: translateY(10px);
}
to {
opacity: 1;
transform: translateY(0);
}
}
.hero {
animation: fade-in 0.4s ease forwards;
}
You can also use percentage stops for finer control.
@keyframes pulse {
0% {
transform: scale(1);
}
50% {
transform: scale(1.05);
}
100% {
transform: scale(1);
}
}
.badge {
animation: pulse 1.5s ease-in-out infinite;
}
The animation shorthand takes: name duration timing-function delay iteration-count fill-mode.
Key properties:
animation-iteration-count: how many times it runs. Useinfiniteto loop.animation-fill-mode: forwardskeeps the final keyframe state after the animation ends. Without it, the element snaps back to its original styles.animation-delay: wait before starting, e.g.0.3s.
What to read next
- Custom Properties : CSS variables for reusable values including animation durations
- Responsive Design : adapting layouts to different screen sizes