惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

人人都是产品经理
人人都是产品经理
博客园_首页
IT之家
IT之家
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
Vercel News
Vercel News
美团技术团队
D
Docker
WordPress大学
WordPress大学
T
Tailwind CSS Blog
酷 壳 – CoolShell
酷 壳 – CoolShell
The Cloudflare Blog
Y
Y Combinator Blog
F
Fortinet All Blogs
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
G
Google Developers Blog
爱范儿
爱范儿
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
月光博客
月光博客
MongoDB | Blog
MongoDB | Blog
S
SegmentFault 最新的问题
GbyAI
GbyAI
Hugging Face - Blog
Hugging Face - Blog
Microsoft Azure Blog
Microsoft Azure Blog
A
About on SuperTechFans

CSS-Tricks

Let’s Use the Emergent CSS random() Function in all the Browsers | CSS-Tricks What’s !important #18: <geolocation>, Syntax ::highlight()ing, named-feature(), and More | CSS-Tricks Creating Web Widgets Using the Document Picture-in-Picture API | CSS-Tricks animation-trigger | CSS-Tricks MicroLighter: Syntax Highlighter | CSS-Tricks WordPress PHP-Only Block Registration | CSS-Tricks Resolved: CSS Class Prefix Selector | CSS-Tricks CSS Navigation Matching, Early Days | CSS-Tricks WordPress.com Student Plan | CSS-Tricks Dark mode toggles: two states are enough | CSS-Tricks What’s !important #17: Custom Highlight API, CSS Navigation Matching, Fixing text-stroke, and More | CSS-Tricks Blocked aria-hidden: The Warning is Right, and Every Fix You've Found is Wrong | CSS-Tricks Animating CSS border-image | CSS-Tricks SmashingConf Freiburg 2026, September 7-10 | CSS-Tricks Using and Styling the Dialog Element | CSS-Tricks 2026 State of CSS, Devs Surveys | CSS-Tricks Gap Decorations Are Now Available, Here’s What’s New | CSS-Tricks What’s !important #16: sibling-index() Animations, Use Cases for the infinity Keyword, Container Stuck Queries, and More | CSS-Tricks writing-mode | CSS-Tricks pointer-events | CSS-Tricks What’s !important #15: Boundary-aware CSS, Time-based CSS, Full-bleed CSS, and More | CSS-Tricks Get Ready For the Powerful CSS border-shape Property! | CSS-Tricks What’s !important #14: Gap Decorations, random(), <select> field sizing, and More | CSS-Tricks The Shifting Line Between CSS States and JavaScript Events | CSS-Tricks translateZ() | CSS-Tricks translateY() | CSS-Tricks translateX() | CSS-Tricks translate() | CSS-Tricks Using Scroll-Driven Animations for Opposing Scroll Directions | CSS-Tricks A First Look at Scroll-Triggered Animations | CSS-Tricks
rotateX() | CSS-Tricks
Gabriel Shoyombo · 2026-05-13 · via CSS-Tricks

The CSS rotateX() function rotates an element around the x-axis in a three-dimensional space. Specifically, it vertically flips the element, making it tilt backward or forward, depending on the angle set. It is one of many transform functions used in the transform property.

The x-axis is the axis of rotation, so the element turns vertically. Imagine a pin is stuck to the left side of an element and it can only turn up or down.

In the demo below, rotateX(0) is given as the element’s default rotation:

.demo-element {
  transform: rotateY(var(--deg));
  transition: transform 0.3s ease;
}

The rotateX() function is defined in the CSS Transforms Module Level 2 specification.

Syntax

rotateX() = rotateX( [ <angle> | <zero> ] )

Arguments

/* angle in degrees */
rotateX(45deg) /* rotates 45 degrees backwards */
rotateX(-90deg) /* rotates 90 degrees forwards */

/* angle in turns */
rotateX(0.5turn) /* rotates 180 degrees (half a full turn) */
rotateX(1turn)   /* Rotates a full 360-degree turn */

/* angle in radians */
rotateX(1.57rad) /* Approximately 90 degrees */

/* angle in gradians */
rotate(200grad)  /* rotates 180 degrees */

The rotateX() function takes a single <angle> argument, which defines how much the element is rotated around its vertical axis.

  • <angles>: values like 45deg0.5turn-90deg1.57rad, etc. can be passed.
  • A positive angle tilts the top of the element toward the back and the bottom toward the front.
  • While a negative angle does otherwise: it tilts the element’s top towards you, and its bottom away from you.

The <angle> type can be one of four units:

  • deg: One degree is 1/360 of a full circle.
  • grad: One gradian is 1/400 of a full circle.
  • rad: A radian is the length of a circle’s diameter around the shape’s arc. One radian is 180deg, or 1/2 of a full circle. One full circle is 2π radians, which is equal to 6.2832rad or 360deg.
  • turn: One turn is one full circle. So, halfway around a circle is equal to .5turn, or 180deg.

Setting up 3D transforms

rotateX() is part of the CSS 3D transform functions, so it’s better represented in a 3D view. For rotateX() to produce a visible 3D effect, you need to set the perspective property on the parent element. The perspective property determines how the element is projected, adding depth to the element and making it look natural and 3D.

In this demo, we have two sliders to control the rotateX() degree and perspective property.

In the absence of perspective, the element looks oddly skewed and ugly.

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 rotateX() is creating flip cards that reveal content on the back when clicked or hovered. You can use this technique for pricing tables, profile cards, or interactive galleries.

To set the stage and give the card a projection value and 3D presence, we set the perspective and preserve-3d styles on 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);
}

Then we position the front and back faces of the card absolutely within the container while setting backface-visibility to hidden:

.flip-card-front,
.flip-card-back {
  position: absolute;
  backface-visibility: hidden;
}

Next, we pre-rotate the back face by 180 degrees, so it is ready to be revealed when the card flips

.flip-card-back {
  transform: rotateX(180deg);
}

And, finally, we flip the card when the parent is :hover-ed:

.flip-card:hover .flip-card-inner {
  transform: rotateX(180deg);
}

Example: 3D Loading spinner

We can also create engaging loading indicators with the rotateX() function..

In this example, we’re not only using the rotateX() function, but we’re combining it with the rotateY() function for a two-axis rotation animation. By continuously rotating an element horizontally and vertically, we create a 3D spinning effect.

Once again, we give the element’s parent a perspective:

.spinner-wrapper {
  perspective: 1000px;
  margin-bottom: 2rem;
}

Then, we apply the animation to the element using the CSS animation shorthand property.

.spinner {
  width: 80px;
  height: 80px;
  animation: spin-3d 2s ease-in-out infinite;
}

Next, we define the keyframe, which dictates how the element rotates from one point to another.

@keyframes spin-3d {
  0% {
    transform: rotateX(0deg) rotateY(0deg);
  }
  25% {
    transform: rotateX(180deg) rotateY(90deg);
  }
  50% {
    transform: rotateX(180deg) rotateY(180deg);
  }
  75% {
    transform: rotateX(360deg) rotateY(270deg);
  }
  100% {
    transform: rotateX(360deg) rotateY(360deg);
  }
}

The order in which the transform functions are defined is important. The effect of the first function comes to life before the second, so at 25% the element flips halfway horizontally before the vertical flip, and the animation is so smooth you hardly notice it.

Example: 3D accordion

Let’s skip the boring accordion component content reveal animation and make ours a bit interesting.

We can enhance traditional accordions by adding a subtle rotateX() rotation when items expand or collapse, creating a more staggered fall effect that further engages the user and improves the experience, rather than the simple slide-down-and-back-up animation.

Once again, as usual, we set the perspective on the parent

.accordion-item {
  perspective: 1000px;
}

Then, we define the transform and transform-origin. Since we want the .accordion-content to fall toward the user, we use a negative 90° angle to shift the element out of the user’s view.

Also, we can change the default rotation axis from the center to the top using transfom-origin: top;

.accordion-content {
  transform-origin: top;
  transform: rotateX(-90deg);
  overflow: hidden;
  transition:
    transform 0.4s ease,
    opacity 0.3s ease,
    max-height 0.4s ease;
}

The transform-origin:top ensures the rotation occurs from the top edge, making it look like a door opening downward, while rotateX(-90deg) makes the content appear to unfold into view.

As the accordion opens, the .accordion-content element falls in a staggered manner to 0 degrees, which is the default position.

.accordion-item.open .accordion-content {
  transform: rotateX(0deg);
  opacity: 1;
  max-height: 500px;
}

A note about transform-origin and rotateX()

By default, the rotateX() function rotates an element around its center. However, you can change this rotation axis using the CSS transform-origin property. transform-origin lets you change the point of origin of any transform function, so rather than being restricted to center, you can use top centertop rightbottom left, or even percentages and lengths.

.child {
  transform: rotateX(120deg);
  transform-origin: top center;
}

Specification

The CSS rotateX() function is defined in the CSS Transforms Module Level 2 draft.

Browser Support

The rotateX() function has baseline support on all modern browsers.