Menu

CSS Rotate: rotate(), the rotate Property and Spinning

Rotate an element with transform: rotate(45deg) or the newer rotate property. Learn angle units (deg, turn, rad), rotating around a corner with transform-origin, rotating text and icons, a spinning loader, and 3D rotation with rotateX and rotateY.

This page includes runnable editors - edit, run, and see output instantly.

Rotate an element

Two ways, same result: the rotate() function inside transform, or the rotate property on its own. Positive angles turn clockwise:

The blue and green boxes are turned exactly the same way, 45 degrees clockwise around their centers. The amber box has a negative angle, so it tilts counterclockwise. Rotation never moves the layout: each box still takes its original 90 by 60 slot, which is why rotated elements can overlap their neighbors.

Angle units

UnitFull circle90 degrees
deg360deg90deg
turn1turn0.25turn
rad6.2832rad1.5708rad
grad400grad100grad

deg is the usual choice; turn reads well for spinning (rotate: 1turn). Angles over 360 are allowed and matter in animations: rotate(720deg) in a keyframe spins twice. Always write the unit: rotate(45) is invalid and ignored.

Drag the slider to see an angle in each unit:

Rotating around a corner: transform-origin

An element turns around its center by default. transform-origin moves the pivot. A clock hand pivots on its end, not its middle:

The hand's bottom end sits on the amber pin at the center of the face, and rotate: 120deg turns it to four o'clock. Remove the transform-origin line and the hand spins around its own middle instead, off the pin.

Rotating text and vertical labels

A small tilt with rotate is fine for a badge or a sticker. For a truly vertical label, writing-mode is better, because it changes the layout: the element becomes tall and narrow instead of overlapping what is next to it.

The readout shows the layout size of each label. The rotated one still takes its original wide, short box: it leaves an empty gap beside it and sticks out above and below its row, into whatever is there. The writing-mode one takes a tall, narrow box. Adding rotate: 180deg makes it read from bottom to top, which is the usual direction for a vertical label.

Rotate an icon on click or hover

Turning an arrow 180 degrees is the standard way to show that a section is open. Combine rotate with a transition:

The chevron is a square with two borders, turned 45 degrees so it points down. When the button is expanded it goes to 225 degrees, pointing up, and the transition animates the half turn. The aria-expanded attribute drives the style, so the visual state and the state screen readers announce can never disagree.

A spinning loader

A spin is a rotation from 0 to 360 degrees, repeated with linear timing so the speed never changes:

With only a to keyframe, the animation starts from the element's own rotation (none) and ends at 360deg, and infinite repeats it without a jump because 360deg looks the same as 0. For people who asked their system for reduced motion, the spinner turns three times slower. More on keyframes on the animation page.

3D rotation: rotateX, rotateY

rotateX() tips an element backward around the horizontal axis and rotateY() turns it around the vertical axis, like a door. Without perspective they just look squashed; perspective on the parent adds depth:

.scene { perspective: 600px; }
.card  { transform: rotateY(35deg); }
.flip  { transform: rotateY(180deg); backface-visibility: hidden; } /* card flip */

To mirror an element rather than turn it, use scale: -1 1 (a horizontal flip). A rotation of 180 degrees turns it upside down, which is not the same thing.

Common mistakes

  • Rotating a <span> or <a> that stays put. Plain inline elements ignore transforms. Add display: inline-block.
  • A rotation that disappears on hover. A hover rule with transform: scale(1.1) replaces transform: rotate(...). Use the separate rotate and scale properties, or list both functions.
  • Expecting the layout to make room. A rotated image keeps its unrotated box and overlaps its neighbors. Give the container the rotated size, or use writing-mode for text.
  • Spinners with ease. The default timing speeds up and slows down every turn. Use linear.
  • Rotating around the wrong point. Set transform-origin before tuning the angle.

Frequently Asked Questions

How do you rotate an element in CSS?

Use transform: rotate(45deg); or the separate property rotate: 45deg;. Positive angles turn clockwise and negative angles turn counterclockwise, around the element's center unless you change transform-origin.

What is the difference between transform: rotate() and the rotate property?

They draw the same result. The rotate property is independent of transform, so a hover rule can change scale or translate without removing the rotation, and each can have its own transition. Together they act like transform: translate() rotate() scale(), whatever order you declare them in.

How do I rotate an image 90 degrees in CSS?

Add transform: rotate(90deg); (or rotate: 90deg;) to the img. The image keeps its original space in the layout, so a tall image rotated to landscape can overlap its neighbors; give its container room for the rotated size.

How do I make an element spin in CSS?

Define @keyframes spin { to { rotate: 360deg; } } and apply animation: spin 1s linear infinite;. Use linear so the speed stays constant, and slow it down or stop it under prefers-reduced-motion: reduce.

How do I rotate text vertically in CSS?

For a vertical label, writing-mode: vertical-rl is usually better than rotate(90deg), because it changes the layout too: the element takes vertical space instead of overlapping. Use rotate for small decorative tilts.

Coddy programming languages illustration

Learn to code with Coddy

GET STARTED