How to Create 3D Button Flip Animations With CSS

Flip animations are popular CSS effects that show both the front and the back of an HTML element by turning them from the top to the bottom, or from left to the right (and vice versa). They are rad in 2 dimensions, but they are even cooler when performed in 3D.

In this post, I’ll show you how to create simple 3D buttons, and add flip animations to them.

You can see the result on the demo below, if you click on the buttons, they’ll perform the labeled flip animation.

1. Creating the HTML for the 3D button

To create a 3D button (with Top → Bottom flip), first we stack three <div>s on each other, two for the front and back faces of the button, and a third one for filling the depth in the middle. We put the three button faces into the .flipBtn container that will function as the 3D button, and we place the 3D button into the .flipBtnWrapper wrapper.

<div class="flipBtnWrapper">
  <div class="flipBtn">
    <div class="flipBtn_face flipBtn_back"></div>
    <div class="flipBtn_face flipBtn_mid"></div>
    <div class="flipBtn_face flipBtn_front"></div>
2. Adding basic styles with CSS

We set the width and height properties of the wrapper, the button, and the button faces, and position them using the relative/absolute positioning technique.

.flipBtnWrapper {
  width: 200px;
  height: 200px;
  position: relative;

.flipBtn_face {
  width: 100%;
  height: 100%;
  position: absolute;
3. Style the 3 button faces

We add background-images to the front and back button faces, and set a cool linear-gradient behind the images for both. The trick here is that in CSS, you can set multiple images as background image for the same element, and you can also declare gradients as background images.

The middle face, .flipBtn_mid, is given a height of 20px, and a same space of 20px is created between the front and back faces. We achieve the latter by using the translateZ() CSS function that moves an element along the z-axis. We push the back face back by 10px, and bring the front face forward by 10px.

.flipBtn_front {
  background-image: url("image/css-3d-flip-button-animation-play.png"),
                    linear-gradient(#FF6366 50%, #FEA56E);
  backface-visibility: hidden;
  transform:  translateZ( 10px );

.flipBtn_back {
  background-image: url("image/css-3d-flip-button-animation-pause.png"),
                    linear-gradient(#FF6366 50%, #FEA56E);
  background-color: blue;
  transform:  translateZ( -10px );

.flipBtn_mid {
  height: 20px;
  background-color: #d5485a;
  transform: rotateX(90deg);
  top: -10px;

To cover the space between the front & back faces with the middle one, we lay the middle face flat across the x-plane of the 3D space using the transform: rotateX(90deg); rule that makes it perpendicular to both the front and back button faces on the y-plane.

Since the middle face was laid flat across the x-plane, its top point on the y-axis goes 10px (half of its height) down from original. So, to pull it back up and align its top with the two other button faces, I added the top: -10px rule as well.

I used the backface-visibility CSS property for the front face, so when we flip the button, the back of the front face will not be visible.

So far, you will only see the front face on the screen, as the x-plane is hidden from view, and on the y-plane (screen) the last face laid down was the front. By rotating the button you will be able to see the other faces as well.

3D Button Before Rotation
The button
4. Rotating the button

The transform-style CSS property determines whether the child elements of an HTML element are displayed flat, or positioned in the 3D space. In the code snippet below, the transform-style: preserve-3d; rule gives 3D volume to our button, while the transform: rotatexX() property rotates it around the x-axis.

.flipBtn {
  transform-style: preserve-3d;
  transform: rotateX( -120deg);

Note that I used -120deg solely for demonstration purposes, as this way it’s easier to illustrate how the button rotation works.

Rotated 3D Button
Button rotated by -120°

However in the next step we will change it to -180deg to make the button completely flip around.

5. Animating the button

At this point, our 3D button is still not animated. We can do this by using the transition property. We use the transform property for the first value, as this is the property we want to apply the transition effect for. The second value, is the duration, 2s.

Let’s make the button only rotate on hover, so instead of the .flipBtn selector, let’s use .flipBtnWrapper:hover .flipBtn. As mentioned earlier, also change the value of rotateX() to -180deg to make the button flip around.

.flipBtn {
  transition: transform 2s;
  transform-style: preserve-3d;

.flipBtnWrapper:hover .flipBtn {
  transform: rotateX( -180deg);

Note that in the Github repo, I added a checkbox to each button in order to fire the animation on :checked rather than on :hover, this way it behaves more like a real button. I also included four different buttons with four flip directions (Top → Bottom, Bottom → Top, Right → Left and Left → Right ), so that you can easily use whichever you want.