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 neat 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 in the demo below. If you click on the buttons, they’ll perform the labeled flip animation.
Read Also: 15 Beautiful Text Effects Created with CSS
1. Creating the HTML for the 3D button
To create a 3D button (with a 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, which will function as the 3D button, and 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> </div> </div>
2. Adding basic styles with CSS
We set the width
and height
properties for 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, .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 linear gradient behind the images for both. The trick here is that in CSS, you can set multiple images as the 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 the same space (20px) is created between the front and back faces. We achieve the latter by using the translateZ()
CSS function, which 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 and 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, which 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 moves 10px (half of its height) down from its original position. So, to pull it back up and align its top with the other two button faces, we added the top: -10px
rule.
We used the backface-visibility
CSS property for the front face so that 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 (the screen), the last face rendered was the front. By rotating the button, you will be able to see the other faces.

4. Rotating the button
The transform-style
CSS property determines whether the child elements of an HTML element are displayed flat or positioned in 3D space. In the code snippet below, the transform-style: preserve-3d;
rule gives 3D volume to our button, while the transform: rotateX()
property rotates it around the x-axis.
.flipBtn { transform-style: preserve-3d; transform: rotateX( -120deg); }
Note that we used -120deg
solely for demonstration purposes, as this makes it easier to illustrate how the button rotation works.

However, in the next step, we will change it to -180deg
to make the button flip completely around.
5. Animating the button
At this point, our 3D button is still not animated. We can achieve this using the transition
property. We use transform
as the first value, as this is the property we want to apply the transition effect to. The second value is the duration: 2s
.
Let’s make the button rotate only on hover. Instead of the .flipBtn
selector, let’s use .flipBtnWrapper:hover .flipBtn
. As mentioned earlier, we also change the value of rotateX()
to -180deg
to make the button flip completely around.
.flipBtn { transition: transform 2s; transform-style: preserve-3d; } .flipBtnWrapper:hover .flipBtn { transform: rotateX( -180deg); }
Note that in the GitHub repo, we added a checkbox to each button to trigger the animation on :checked
rather than :hover
, making it behave more like a real button. We also included four different buttons with four flip directions (Top → Bottom, Bottom → Top, Right → Left, and Left → Right), so you can easily use whichever you want.