CSS Transforms and Transitions: How to Use Them
Learn how CSS transforms change an element’s visual position and shape, how transitions animate those changes, and how to handle timing and reduced motion.
A CSS transform changes an element’s visual position, shape, or orientation without changing normal document flow. A transition controls how gradually a property changes between values. To animate a transform, set the starting transform, add a transition for the transform property, and provide a different transform in a state such as :hover, :focus-visible, or a class.
<button class="card">Open details</button>
.card {
transform: translateY(0);
transition: transform 180ms ease;
}
.card:hover,
.card:focus-visible {
transform: translateY(-4px);
}
@media (prefers-reduced-motion: reduce) {
.card {
transition: none;
}
.card:hover,
.card:focus-visible {
transform: none;
}
}
Here, transform supplies the movement; transition animates the change. The focus state makes the effect available to keyboard users too. The reduced-motion rule removes this non-essential movement for people who have requested less motion.
1. What transforms and transitions do
A transform changes how an element is drawn in its visual coordinate space. It does not move surrounding elements to make room for the transformed result. A transition is timing behavior for a property-value change; it does not choose the new value or trigger a state change by itself.
| Need | Use | Example |
|---|---|---|
| Move without reflow | translate() or translateX()/translateY() |
transform: translateY(-4px) |
| Turn around a point | rotate() |
transform: rotate(8deg) |
| Change visual size | scale() |
transform: scale(1.05) |
| Slant | skew() |
transform: skewX(-5deg) |
| Animate a value change | transition |
transition: transform 180ms ease |
| Make surrounding content reflow | A layout property or a different layout approach | A transform alone does not reflow neighbors |
Use layout properties when the document’s geometry should change and neighbors should move. Use transforms when the effect is visual and an overlay or movement that leaves layout in place is intended. See MDN’s guides to CSS transforms and CSS transitions.
2. Common transform functions
Translate: move visually
.badge {
transform: translate(8px, -3px);
}
The first value moves along the horizontal axis and the second along the vertical axis. A positive vertical translation moves down; a negative one moves up. The element keeps its original space in the layout.
Rotate: turn around an origin
.icon {
transform-origin: center;
transform: rotate(12deg);
}
transform-origin sets the point around which the transform operates. Change it when an element should pivot from an edge or corner rather than its center.
Scale: enlarge or shrink
.thumbnail:hover {
transform: scale(1.04);
}
A scale above 1 enlarges the element visually; a value between 0 and 1 shrinks it. Because layout dimensions do not expand with the visual size, a scaled element can overlap nearby content or be clipped by an ancestor with overflow clipping.
Skew and compose transforms
.label {
transform: translateX(4px) rotate(-3deg) scale(1.02);
}
You can list multiple transform functions in one declaration. Their written order matters because the operations compose in that order. If the result seems to move along an unexpected axis, inspect the order and try one function at a time. For 3D effects, CSS also provides functions such as perspective() and rotateY(); start with a simple 2D effect unless depth is necessary.
CSS also provides individual translate, rotate, and scale properties. MDN documents their order as translate, rotate, scale, then transform. Use the form that makes the effect easiest to understand and maintain.
3. Configure a transition
The transition shorthand accepts a property, duration, timing function, and delay. For example:
.panel {
transform: translateY(0);
transition: transform 180ms ease 0s;
}
.panel.is-open {
transform: translateY(12px);
}
| Control | What it means | Example |
|---|---|---|
| Property | Which property change should animate | transform |
| Duration | How long the change takes | 180ms |
| Timing function | How the pace changes over time | ease, linear, ease-in, ease-out |
| Delay | How long to wait before starting | 0s |
Name the property you intend to animate, such as transform, instead of defaulting to transition: all. A broad transition can animate unrelated changes and make later styling harder to reason about. Avoid relying on transitions to or from auto: user-agent behavior can differ, so choose explicit values or another approach when a dependable interpolation matters. See MDN’s transition guide.
4. Respect reduced-motion preferences
Some people set their operating system or device to request less motion. Use prefers-reduced-motion to suppress or reduce non-essential movement, and verify that the non-animated state remains clear and usable.
.menu-item {
transform: translateX(0);
transition: transform 160ms ease-out;
}
.menu-item:hover,
.menu-item:focus-visible {
transform: translateX(6px);
}
@media (prefers-reduced-motion: reduce) {
.menu-item {
transition: none;
}
.menu-item:hover,
.menu-item:focus-visible {
transform: none;
}
}
This is an implementation technique for honoring a preference, not a standalone guarantee of accessibility conformance. W3C’s Technique C39 describes the media-query approach for interaction-triggered motion and explains that techniques are examples, not requirements. MDN documents the prefers-reduced-motion media feature.
5. Do-it-yourself: inspect the effect in a browser
- Save the HTML and CSS example in a local page, or add the rules to the component stylesheet.
- Trigger the state with a pointer and with a keyboard. For keyboard interaction, use a real focusable control and check
:focus-visible. - Temporarily change the duration and timing function to compare the feel. Confirm the effect communicates state without delaying an action.
- Enable the operating system’s reduced-motion preference and verify the media query removes non-essential motion without hiding information.
- Inspect the result at the target viewport and check for clipping, overlap, or confusing stacking.
Common issues and fixes
| Symptom | Likely cause | Fix |
|---|---|---|
| It jumps instead of animating | The transition is missing, targets a different property, or the state does not change the expected value. | Put the transition on the element’s base rule and confirm both states set compatible transform values. |
| Other content does not move with the element | Transforms change visual placement, not normal flow. | Use a layout change if surrounding content must reflow. |
| It pivots around the wrong point | The default transform origin is not the desired pivot. | Set transform-origin explicitly. |
| It animates unrelated changes | transition: all includes more properties than intended. |
Name the property to transition. |
| It is clipped or covers another item | The transformed visual bounds overlap or an ancestor clips overflow. | Check ancestor overflow and stacking, and reserve visual room where appropriate. |
z-index behaves unexpectedly |
A non-none transform creates a stacking context. |
Inspect stacking-context ancestors; a child cannot stack outside its parent’s context. |
| A fixed-position child moves with the transformed parent | A transformed element can become the containing block for positioned descendants. | Move the fixed element outside that transformed ancestor if it must remain viewport-relative. |
| The motion persists for someone who requested less | The reduced-motion preference is not handled, or only one interaction state was covered. | Add a reduced-motion media query and check hover, focus, and other triggers. |
MDN’s reference for the transform property covers its stacking-context and containing-block effects.
6. Performance, reliability, and cost
CSS transforms and transitions are browser features and do not require a paid screenshot service. Keep effects focused, avoid broad transitions that animate unintended properties, and check the result on the devices and pages you support. This guide makes no browser performance or compatibility benchmark claims; consult current references and test your target environment when those details matter.
For documentation, bug reports, or visual review, a screenshot can preserve a rendered state. You can capture it manually in a browser or use a screenshot API. ScreenshotNeo is a website screenshot API and MCP server; it can capture a URL as PNG, JPEG, WebP, or PDF. Its consent-banner and popup cleanup can be disabled per step. See ScreenshotNeo for product information.
7. Or skip the browser setup
Make one GET request with the page URL. Replace YOUR_API_KEY with your key and adjust the output extension if you request a different image format. The API options and response details are in the ScreenshotNeo API documentation.
curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://stripe.com -o shot.webp
import requests
r = requests.get(
"https://api.screenshotneo.com/v1/shot",
params={"access_key": "YOUR_API_KEY", "url": "https://stripe.com"},
timeout=90,
)
r.raise_for_status()
open("shot.webp", "wb").write(r.content)
const q = new URLSearchParams({ access_key: 'YOUR_API_KEY', url: 'https://stripe.com' });
const res = await fetch(`https://api.screenshotneo.com/v1/shot?${q}`);
if (!res.ok) throw new Error(`Screenshot request failed: ${res.status}`);
const bytes = new Uint8Array(await res.arrayBuffer());
await import('node:fs/promises').then(fs => fs.writeFile('shot.webp', bytes));
- Cookie banners, popups, and chat widgets are removed before the shot.
- Bot checks, blank pages, and failed loads are never billed.
- An MCP server lets AI agents take screenshots.
- 1,000 screenshots a month are free with no card; paid plans start at $5 for 3,000.
Sign up for 1,000 free screenshots a month, with no card required.
8. FAQ
Does transform change an element’s width in the layout?
No. It changes the visual rendering; the element’s original layout space remains.
Can I transition a transform?
Yes. Set a transition for transform on the base rule, then change the transform value in another state.
Should every hover effect move an element?
No. Use movement only when it helps communicate interaction or state, and provide a usable reduced-motion experience.
Why does transform order matter?
Multiple transform functions compose in their written order, so changing that order can change the resulting visual movement.


