How to use css perspective animation for awesome effects!
Tags: css, perspective, 3danimation, tutorial
Published: 2022-06-22 20:00:44

Animation is one of the most essential techniques used in the design and development of websites. It can help to create a more engaging and user-friendly experience for users, as well as adding an element of fun and excitement.

In this article, we will be looking at some of the css perspectives that can be used when creating animation.


## What is css perspective 3d?

CSS perspective 3D is a web development technique that enables web browsers to display three-dimensional (3D) images using the CSS 3D transforms specification. 

It works by simulating the placement of an object in three-dimensional space, then projecting that object onto the screen. This gives developers more control over how 3D objects are displayed, and allows them to create more sophisticated and realistic visuals.

## How to use css perspective 3d

With CSS perspective 3D, you can add depth and dimension to your web pages easily. This powerful feature can help you create stunning visual effects that will wow your visitors. 

Here's how to use basic CSS perspective 3D to.

1. Create a container element on your page. This can be a <div> or any other element that will hold your content. 

2. Add the following CSS properties to the container:
`perspective: 1000px;` This is the distance from the viewer to the z=0 plane 
`transform-style: preserve-3d;` This tells the browser to preserve the 3D positions of immediate child elements

Now, any child elements inside your container can have 3D positions relative to the container. You can move them around in 3D space using the transform property.

## Examples of css perspective 3d in action

Let's do a cool experiment to animate objects in 3d.
I am going to create the below animation just by using CSS.

{% codepen https://codepen.io/imjignesh/pen/vYKqZvJ %}

This experiment was inspired by a cool video game when I was young.

Let's understand the process in 3 simple steps. 
1. Setup Stage
2. Animate Using @keyframes
3. Enable Perspective And Transform

Why animate first and then apply Perspective?
We'll these steps can be swapped. But it's good the see how your elements will look in perspective if they're animating. This way it is easy to adjust transforms from all viewing direction.

### Step 1. Setup Stage

As discuss earlier, we just need to apply perspective to a parent element. We'll call it a parent. 

```
<div class="parent">...</div>
```

This parent CSS will hold everything to enable 3d perspective.

```
/* Setting up perspective distance relative to window size. */
.parent {
  overflow: hidden;
  width: 100%;
  perspective: 50vw;
  perspective-origin: 50% 0%;
}
```

Then we'll create a stage to put levels inside.
We'll use absolutely positioned elements with CSS Transforms. I have already covered [Basics of CSS Perspective](https://imjignesh.com/how-css-perspective-works/) and about [CSS Positions](https://imjignesh.com/how-to-use-css-position-property/) in depth for understanding of properties and its values.

```
<div class="stage">
   <div class="level" style="--level: 180deg; --w: 55%">
   ...
   ...
   </div>
</div>
```

This stage will [use flexbox properties](https://imjignesh.com/how-to-use-display-flex-css/) to stack levels on top of each other and `transform-style:preserve-3d` to enable 3d on child elements.

```
.stage {
  width: 100%;
  background: #000;
  display: flex;
  flex-direction: column;
  /* All the cild elements inside this container will preserve 3d space */
  transform-style: preserve-3d;
  border-bottom: 50px solid #2196f3;
  padding-bottom: 30px;
}
```

Each level will have the following html structure.

```
<div class="level" style="--level: 180deg; --w: 55%">
    <span></span>
    <span></span>
    <span></span>
    <div>9</div>
</div>
```

These empty div elements are just placeholders to hold some geometry for the levels.

The basic CSS code for these geometry blocks looks like this:

```
/* Stage */

.level > span:nth-child(2) {
  width: 100%;
  height: 30px;
  display: block;
  position: absolute;
  background: url(brick.png) repeat right
    bottom / 30px 30px;
  transform: rotateX(180deg) translateZ(-60px);
  top: 100%;
  outline: 2px solid transparent;
  transform-origin: top center;
  z-index: 2;
  backface-visibility: visible;
  width: var(--w);
}

/* Mountains */
.level > span {
  z-index: 1;
  position: absolute;
  left: 0;
  top: 0;
  bottom: 30px;
  width: 205px;
  transform-style: preserve-3d;
}

.level > span:nth-child(1):before {
  content: "";
  position: absolute;
  left: 0;
  top: 0;
  bottom: 0px;
  background: url(mountain.png) bottom
    right / auto 100%;
  width: 100%;
  transform: translateZ(40px);
  backface-visibility: visible;
}

.level > span:nth-child(3),
.level > span:nth-child(2),
.level:after,
.level:before,
.level *:after,
.level *:before {
  filter: hue-rotate(var(--level));
}
.characters {
  transform: translateZ(30px) translateX(-50%);
  left: 50%;
  position: absolute;
  bottom: 30px;
}
.bird {
  z-index: 2;
  transform: translateZ(30px) translateX(-50%);
  left: 50%;
  position: absolute;
  width: 150px;
  top: 30px;
}

```

This geometry is just about placing absolutely positioned element in flex-box child.

{% codepen https://codepen.io/imjignesh/pen/ExQBPNm %}


### Step 2. Animate Using @keyframes

At this stage We'll add @keyframes to animate the stage. 
This simple keyframes will allow us to transform the child of the stage in 3d space. 

CSS keyframes looks like this:

```
@keyframes stage {
  from {
    transform: translateY(0%);
  }

  to {
    transform: translateY(calc(-100% + 100vh));
  }
}
```

And we add it to the stage with some interval.

```
.stage {
  ...
  animation: stage alternate 10s infinite linear;
}

```

At this point animated stage will look like this.

{% codepen https://codepen.io/imjignesh/pen/gOvNaov %}

### Step 3. Enable Perspective And Transform

We'll add Few more Pseudo elements to the existing geometry. 
The complete geometric code looks like this:

```
.level > div {
  position: absolute;
  left: 60px;
  top: 0;
  width: 100px;
  height: 100%;
  line-height: 200px;
  font-size: 50px;
  color: black;
  transform: translateZ(41px);
  text-align: center;
  font-family: monospace;
  font-weight: bold;
}

/* Stage */
.level:before {
  content: "";
  width: 100%;
  height: 60px;
  display: block;
  position: absolute;
  background: url(brick.png) repeat right
    bottom / 30px 60px;
  transform: rotateX(90deg) translateZ(-60px);
  bottom: 30px;
  outline: 2px solid transparent;
  transform-origin: top center;
  backface-visibility: visible;
  align-self: flex-end;
  width: var(--w);
}

.level:after {
  content: "";
  width: 100%;
  height: 60px;
  display: block;
  position: absolute;
  background: url(brick.png) repeat right
    bottom / 30px 60px;
  transform: rotateX(90deg) translateZ(-60px);
  bottom: 0px;
  outline: 2px solid transparent;
  transform-origin: top center;
  backface-visibility: visible;
  width: var(--w);
}

.level > span:nth-child(2) {
  width: 100%;
  height: 30px;
  display: block;
  position: absolute;
  background: url(brick.png) repeat right
    bottom / 30px 30px;
  transform: rotateX(180deg) translateZ(-60px);
  top: 100%;
  outline: 2px solid transparent;
  transform-origin: top center;
  z-index: 2;
  backface-visibility: visible;
  width: var(--w);
}

/* Mountains */
.level > span {
  z-index: 1;
  position: absolute;
  left: 0;
  top: 0;
  bottom: 30px;
  width: 205px;
  transform-style: preserve-3d;
}

.level > span:nth-child(1):before {
  content: "";
  position: absolute;
  left: 0;
  top: 0;
  bottom: 0px;
  background: url(mountain.png) bottom
    right / auto 100%;
  width: 100%;
  transform: translateZ(40px);
  backface-visibility: visible;
}

.level > span:nth-child(3) {
  position: absolute;
  left: 0;
  top: -12px;
  bottom: -2px;
  background: url(mountain.png) bottom
    right / 150% 150%;
  width: 80px;
  left: 134px;
  transform: rotateY(90deg) rotateX(22deg);
  backface-visibility: visible;
}

.level > span:nth-child(3),
.level > span:nth-child(2),
.level:after,
.level:before,
.level *:after,
.level *:before {
  filter: hue-rotate(var(--level));
}

.characters {
  transform: translateZ(30px) translateX(-50%);
  left: 50%;
  position: absolute;
  bottom: 30px;
}

.bird {
  z-index: 2;
  transform: translateZ(30px) translateX(-50%);
  left: 50%;
  position: absolute;
  width: 150px;
  top: 30px;
}

```

If this geometry looks too difficult, You can check out my article on [CSS Perspective Transform](https://imjignesh.com/how-to-use-transforms-in-perspective/) to understand how and why we use 3d transform to put elements in proper location while using CSS Perspective.

Once All the additional geometrical elements are in place, We'll have this:

{% codepen https://codepen.io/imjignesh/pen/vYKqZvJ %}

If you know how to move elements in perspective You can create really cool effects just by using a few lines of code.

## Pros and cons of css perspective 3d
Pros: It looks cool in browser to have 3d elements on webpage.
Cons: It is too limited and It's not real 3D. 

## What's the verdict?

In conclusion, using perspective animation can be a great way to improve the User Experience of your website or application. By using perspective animation, you can create an illusion of depth and make your website or application more visually appealing. Additionally, perspective animation can be used to convey information to the user in a clear and concise manner. Finally, using perspective animation is a great way to add interactivity to your website or application.