The CSS rotateY() function rotates an element around its vertical y-axis. Specifically, it horizontally flips an element from left to right (or right to left for that matter). It is one of many transform functions used along with the transform property.
The y-axis is the axis of rotation, so the element turns horizontally. Imagine a pin is stuck to the top of an element and it can only rotate left or right.
.demo-element
transform: rotateY(var(--deg));
transition: transform 0.3s ease;
The rotateY() function is defined in the CSS Transforms Module Level 2 specification.
Syntax
rotateY() = rotateY( [ <angle> | <zero> ] )Arguments
/* <angle> in degrees */
rotateY(90deg) /* Element rotates 90 degrees to the right */
rotateY(-180deg) /* Element rotates 180 degrees to the left */
/* <angle> in turns */
rotateY(0.5turn) /* Element rotates 180 degrees (half a full rotation) */
rotateY(1turn) /* Element completes a full 360-degree rotation */
/* <angle> in radians */
rotateY(1.57rad) /* Approximately 90 degrees to the right */
rotateY(-3.14rad) /* Approximately 180 degrees to the left */The rotateY() function takes a single <angle> argument, which defines how much the element is rotated around its vertical axis.
<angles>: Values like45deg,0.5turn,-90deg,1.57rad, etc. When it is a positive angle, the right edge of the element rotates away from you (the element appears to rotate to the right). When the angle is a negative value, the left edge rotates and the element appears to rotate to the left.
The <angle> type has four units to choose from:
deg: One degree is1/360of a full circle.grad: One gradian is1/400of a full circle.rad: A radian is the length of a circle’s diameter around the shape’s arc. One radian is180deg, or1/2of a full circle. One full circle is 2π radians, which is equal to6.2832rador360deg.turn: One turn is one full circle. So, halfway around a circle is equal to.5turn, or180deg.
Setting up 3D transforms
We’ve gotta talk about this first because, for any 3D transform function to create a visible 3D effect, you have to set the perspective property on the parent element. perspective defines the projection of the 3D element from the viewer’s eyes.
Lower values (like 400px) make the 3D element appear closer, while higher values (like 2000px) make it appear farther, reducing the visibility of the 3D effect.
.parent
perspective: 1000px;
.card
transform: rotateY(45deg);
Without perspective, the rotation will appear flat and shrunken, and the 3D depth won’t be visible.

While with perspective, it looks slightly tilted to the right

It’s also worth setting transform-style to preserve-3d, which determines if that element’s children are positioned in 3D space, or flattened.
Basic usage
One of the most popular uses of rotateY() is creating horizontal flip cards that show content on the back when clicked or hovered. To make one, we first set the 3D stage and projection by applying transform-style to preserve-3d; to the card and perspective to 1000px; styles to the parent elements.
.flip-card
perspective: 1000px;
.flip-card-inner
transform-style: preserve-3d;
transition: transform 0.8s cubic-bezier(0.175, 0.885, 0.32, 1.275);
Next, we position the front and back faces of the card absolutely within the container, while setting backface-visibility to hidden. It prevents the content of each face from showing through when rotated to the other side.
.flip-card-front,
.flip-card-back
position: absolute;
backface-visibility: hidden;
We also need to pre-rotate the back face by 180deg. This ensures the back face is readable when flipped and viewed from the front.
.flip-card-back
transform: rotateY(180deg);
And, finally, we flip the card when the parent is :hover-ed.
.flip-card:hover .flip-card-inner
transform: rotateX(180deg);
Example: Image carousel
The rotateY() function is also perfect for creating 3D image carousels that showcase products or galleries. Each item can be positioned around a cylinder and rotated to show the viewer.
Once again, as usual, we set up the 3D stage with perspective and preserve-3d.
.carousel
perspective: 1200px;
.carousel-container
transform-style: preserve-3d;
transition: transform 0.8s cubic-bezier(0.4, 0, 0.2, 1);
Afterwards, we try to position all .carousel-item in the center of the .carousel-container using absolute positioning
.carousel-item
position: absolute;
left: 50%;
top: 50%;
transform: translate(-50%, -50%);
Later, we reposition them to form a cylinder around the .carousel-container using rotateY(calc(var(--n) * 72deg)), which pushes each item forward with translateZ(400px), without which the items would edge into one another.
400px serves as the cylinder’s radius. I tried different radii from 100 to see which one would make each item appear individually, and 400px won.
.carousel-item
position: absolute;
left: 50%;
top: 50%;
transform: translate(-50%, -50%) rotateY(calc(var(--n) * 72deg)) translateZ(400px);
Each .carousel-item has a variable, --n: x, where x is a number from 0 to 4. Since there are five total items, we found the perfect angle for the rotateY() function by dividing 360deg (a full turn) by 5 to get 72deg
Now we use JavaScript to rotate the .carousel-container by 72deg when the “Next” and “Prev” buttons are clicked. This pushes the next or previous panel to the front, depending on the button you click.
let currentRotation = 0;
const anglePerItem = 72;
function rotateCarousel(direction)
currentRotation += direction * anglePerItem;
carouselContainer.style.transform = `rotateY($currentRotationdeg)`;
nextBtn.addEventListener("click", () =>
rotateCarousel(1);
);
prevBtn.addEventListener("click", () =>
rotateCarousel(-1);
);Example: Page turn
Remember the horizontal flipping card we looked at earlier? We can build off of it to make it look like a book page turn.
We’re going to add the transform-origin property to it. It defines the point on the axis at which the rotation occurs. By default, it’s the center, and that’s what we’ve used so far, but we’re changing it here to left center. The new position allows the element to be flipped from the center of the left edge, as in books, rather than from the main center in the flipping card effect.
.page
transform-origin: left center;
transform-style: preserve-3d;
transition: transform 1.5s cubic-bezier(0.645, 0.045, 0.355, 1);
The rotateY() function, when combined with transform-origin: left center;, can create a realistic page-turning effect for digital books, portfolios, or storytelling interfaces.
You should know how to use rotateY() by now, so let’s skip to the magic. Only the right page is animated, so that’s where the transform is focused. We gave .page a transform-origin of left center; so it rotates on the vertical axis around the center of the left end.
Then, when the .turning class is triggered on clicking the page, rotateY(-180deg) flip it over around the defined rotation point.
.page.turning
transform: rotateY(-180deg);
To prevent the content of the page’s front and back from showing through, we use backface-visibility: hidden; to hide it when it’s turned over.
.page-front,
.page-back
backface-visibility: hidden;
Also, we pre-rotate the back page so the content isn’t inverted when it’s turned toward the viewer.
.page-back
transform: rotateY(180deg);
Specification
The CSS rotateY() function is defined in the CSS Transforms Module Level 2 draft.
Browser support
The rotateY() function is supported on all modern browsers.
rotateY() originally handwritten and published with love on CSS-Tricks. You should really get the newsletter as well.