CSS Transform Generator

Build a CSS transform visually. Drag the sliders for translate, rotate, scale and skew, add 3D rotateX/rotateY with perspective, set the transform-origin, try the flip, tilt and grow presets, then copy the ready-to-use CSS. Everything runs in your browser — nothing is uploaded.

3D transforms
Preview on:
Transform

How to use this CSS transform generator

  1. Move it — use Translate X/Y to slide the box. A translate never changes the layout around it, so nothing else on the page shifts.
  2. Rotate itRotate (Z) spins the box in the plane of the screen. It pivots around the transform-origin, which starts at the centre.
  3. Resize itScale X/Y stretch or shrink the box; a negative value mirrors it. Set both equal for a uniform resize.
  4. Slant itSkew X/Y tilt the box into a parallelogram.
  5. Go 3D — open 3D transforms, raise Perspective off zero, then use Rotate X/Y and Translate Z for depth. Perspective is always written first in the output.
  6. Copy the CSS — click Copy and paste the transform rule into your stylesheet. A transform-origin line is added only when you change the origin.

transform function reference

FunctionExampleWhat it does
translate()translate(20px, -10px)Moves the element by X and Y. translateX()/translateY() do one axis.
rotate()rotate(45deg)Rotates in the 2D plane around the transform-origin. Positive is clockwise.
scale()scale(1.2, 0.8)Resizes. One value scales both axes; a negative value flips that axis.
skew()skewX(12deg)Slants the element into a parallelogram along X and/or Y.
rotateX() / rotateY()rotateY(40deg)Rotates around a 3D axis. Needs perspective to look three-dimensional.
translateZ()translateZ(30px)Moves toward (positive) or away from the viewer in 3D space.
perspective()perspective(500px)Depth of the 3D scene. Must be the first function in the list; smaller = more dramatic.
matrix()matrix(1,0,0,1,0,0)The low-level 2D form every other function ultimately compiles to.

Units matter: translate distances take a <length> (px, %, em…), rotate/skew take an <angle> (deg, rad, turn), and scale takes a unitless number.

Common transform patterns

  • Perfect centering — position an element at 50%/50% then transform: translate(-50%, -50%) pulls it back by half its own size to sit dead centre, whatever its dimensions.
  • Hover growtransform: scale(1.05) on :hover gives a subtle lift; because scale is composited it stays smooth.
  • Mirror an iconscaleX(-1) reuses one asset for both directions (e.g. a left/right arrow).
  • Tilt / 3D cardperspective(800px) rotateY(15deg) gives a product card a gentle three-dimensional lean.
  • Flip card — rotate a face rotateY(180deg) with backface-visibility: hidden on both faces to build a two-sided flip.
  • Slide-in — animate from translateX(-100%) to translateX(0) instead of animating left, so no layout is recalculated per frame.

Where CSS transforms came from

CSS transforms began as an Apple / WebKit feature. The 2D -webkit-transform property first shipped in Safari 3.1 in 2008, and Apple followed it with 3D transforms and perspective in Safari 4 (2009), driven by the iPhone’s hardware-accelerated interface. Mozilla added -moz-transform in Firefox 3.5 the same year, and the idea was written up as the CSS Transforms specification, which the W3C later consolidated into the single CSS Transforms Module Level 1 covering both the 2D and 3D features. By around 2013 every major engine supported it unprefixed, and it is now a “Baseline, widely available” feature.

A significant addition arrived much later. For over a decade the only way to apply motion was the transform shorthand, which meant animating just the rotation of an element forced you to restate its translate and scale too. The individual transform propertiestranslate, rotate and scale as standalone properties — reached Baseline across Chrome, Firefox and Safari in 2022, letting you set and animate each independently. They compose in a fixed order (translate, then rotate, then scale) and are applied before any functions still listed in the transform property.

Why the order of functions changes the result

A transform is a list of functions, and the browser combines them by multiplying their matrices in the order written. Because matrix multiplication is not commutative, swapping two functions generally produces a different picture. The intuition that usually helps: each function transforms the coordinate grid that the next function then operates in, so the rightmost function is effectively applied to the element first and the leftmost last.

The classic example is translate versus rotate. transform: translate(100px) rotate(45deg) moves the element 100px to the right and then rotates it in place, so it ends up 100px right and tilted. transform: rotate(45deg) translate(100px) rotates the coordinate axes first, so the following 100px translate now runs along a diagonal — the element lands somewhere different. Neither is “correct”; they are two different compositions. This generator emits a fixed, predictable order (perspective, translate, rotate, rotateX, rotateY, translateZ, scale, skew); if a design needs a specific composition, reorder the functions in the copied string.

Perspective and the two ways to set it

3D rotations look flat until you add perspective, which tells the browser how far the viewer is from the plane of the screen. A small value such as 300px puts the camera close, exaggerating the depth so a rotated face fans out dramatically; a large value like 1500px is like standing far back, giving a gentle, almost orthographic tilt. Setting it to zero (this tool’s default) simply switches 3D depth off.

There are two ways to apply it, and they are not the same. The perspective() function — which this generator emits, and which must be the first item in the list — applies perspective to that one element’s own 3D transform. The perspective property, set on a parent, gives all of its children a single shared vanishing point, which is what you want when several 3D cards should look like they sit in the same scene. Pair either with transform-style: preserve-3d on a container when you need nested elements to keep their own depth rather than being flattened.

Performance: why transforms are the animation you want

A browser renders a frame in stages — recalculate styles, lay out geometry, paint pixels, then composite the layers together. Most CSS properties, if animated, force the expensive early stages: changing width, top or margin triggers a layout reflow and a repaint on every frame. transform and opacity are special: the browser can hand them to the compositor thread and run them on the GPU, skipping layout and paint entirely, which is how animations stay at 60fps even on cheaper phones.

The practical takeaway is to express motion as transforms: translate instead of top/left, scale instead of width/height. You can nudge the browser to promote an element to its own layer ahead of time with will-change: transform, but use it sparingly — every promoted layer costs memory, and blanketing a page with will-change can slow things down more than it helps. Add it just before an animation that needs it, and remove it when the animation is done.

Common mistakes (and the fixes)

  • Expecting the layout to move. A transform is visual only; the element keeps its original box. If you need surrounding content to reflow, transform is the wrong tool — change the box model instead.
  • Blurry text after a transform. Sub-pixel translate or fractional scale can soften rendering. Snap translate values to whole pixels, or add transform: translateZ(0) to force a cleaner layer where it matters.
  • 3D rotation looks flat. You forgot the perspective. A rotateY with no perspective just squashes the element horizontally; raise perspective off zero.
  • Wrong pivot. A rotation swinging from an unexpected point usually means the transform-origin is not where you assumed — it defaults to the centre, not a corner.
  • Order surprises. Combining translate and rotate in the wrong order sends an element off to an unexpected spot; remember the rightmost function is applied first.
  • Overusing will-change. Leaving will-change: transform on many elements permanently wastes GPU memory. Scope it to what is actually animating.

Frequently asked questions

What order are CSS transform functions applied in?

The functions in a transform list are combined by multiplying their matrices in the order you write them, so the order changes the result. A useful way to think about it: each function transforms the coordinate system that the next one uses, so the rightmost function is effectively applied to the element first and the leftmost last. That is why "translate(100px) rotate(45deg)" (move right, then rotate in place) looks different from "rotate(45deg) translate(100px)" (rotate the axes first, then move along the now-rotated X). This generator writes the functions in a fixed, readable order — perspective, translate, rotate, rotateX, rotateY, translateZ, scale, skew — so the output is predictable; if you need a different order, edit the copied string.

Does a CSS transform change the page layout?

No. A transform is purely visual: the element still occupies its original box in the document flow, so surrounding elements do not move to make room and nothing reflows. That is exactly why transforms are cheap to animate. Two side effects are worth knowing: a transformed element creates a new stacking context (so z-index is judged within it), and any value other than "none" makes the element a containing block for its position:fixed and position:absolute descendants.

What is the perspective value for, and where does it go?

Perspective is what makes 3D rotations look three-dimensional instead of flat — it sets how far the viewer is from the z=0 plane, so a smaller number (say 300px) gives a stronger, more dramatic foreshortening and a larger number (1500px) a subtle one. When you use the perspective() transform function it must be the first function in the list, which is why this tool always emits it first. If you want one shared vanishing point for several children, use the "perspective" property on their common parent instead of the function on each child.

How do I flip an element horizontally or vertically?

Scale by a negative factor on that axis. "transform: scaleX(-1)" mirrors an element left-to-right (a horizontal flip), and "scaleY(-1)" mirrors it top-to-bottom (a vertical flip). Use the Flip Horizontal / Flip Vertical presets here to see it. Negative scale is the standard, GPU-friendly way to mirror an icon or image without a second asset.

What does transform-origin do?

transform-origin sets the point that rotate, scale and skew pivot around; it defaults to the centre of the element (50% 50%). Change it to a corner and a rotation swings from that corner like a hinge, or a scale grows out of it. It has no visible effect on a pure translate, since moving an element does not depend on a pivot. This generator lets you pick common origins (centre, the four sides, the four corners) and adds a transform-origin line to the output whenever it is not the default centre.

Why are transform and opacity the best properties to animate?

Modern browsers can animate transform and opacity on the compositor (GPU) thread without recalculating layout or repainting pixels, so they can hit a smooth 60fps even on modest devices. Animating layout properties like width, top or margin instead forces the browser to recompute geometry and repaint every frame, which is far more expensive and often janky. The practical rule is to express motion and resizing as transforms — translate instead of top/left, scale instead of width/height — and add "will-change: transform" only when you actually need the hint, since overusing it wastes memory.

Explore more tools

Browse all 63 tools →