3D Effect with CSS

Exploring CSS perspective, transforms, and 3D positioning to create immersive visual effects

Introduction

The CSS perspective property enables 3D positioning on elements, creating depth and immersive visual effects. It determines the distance between the user and the z = 0 plane, where lower perspective values give larger transforms and higher values give smaller ones.

In this guide, we'll explore how to use CSS perspective, transforms, and 3D positioning to create engaging interactive experiences. We'll cover perspective properties, vanishing points, child transformations, and preserving 3D space through nested elements.

Perspective

There are 2 ways to handle perspective in CSS: the first is with the perspective property, and the second is with the transform property with perspective() as a function.

perspective.css
.perspective-parent {
    transform-style: preserve-3d;
    perspective-origin: 50% 50%;
    perspective: 300px;
}

.perspective-child {
    transform: translate3d(0px, 0px, -100px);
}
300 px

Perspective Transform Function

The perspective transform function is an easy and quick way to transform a single element. However, it will maintain its own vanishing point. This means that the 3d effect is independent from other elements, even if they have the same perspective.

60 deg

Perspective Property

The perspective property will affect all children inside, allowing them to maintain the same vanishing point.

60 deg

Vanishing Point (Origin)

The perspective-origin property can define a vanishing point on our container. Its default value is centered horizontally and vertically at 50% 50%.

300 px
50 %
50 %
vanishing-point.css
.perspective-parent {
    transform-style: preserve-3d;
    perspective-origin: 50% 50%;
    perspective: 300px;
}

.perspective-child {
    transform: translate3d(0px, 0px, -100px);
}

Child Transformations

We can perform several transformations on child components within a parent container with a perspective. The main transformations you might do on a child would be increasing/decreasing scale, rotating on an axis, or translating its position within the perspective container.

Container
300 px
50 %
50 %
Child - Translate
0 px
0 px
-500 px
Child - Scale
1
1
1
Child - Rotate
0 deg
0 deg
0 deg
child-transforms.css
.perspective-parent {
    transform-style: preserve-3d;
    perspective-origin: 50% 50%;
    perspective: 300px;
}

.perspective-child {
    transform: ;
}

Preserve 3D

We can preserve 3d perspective into grandchildren elements on a container by using the transform-style: preserve-3d;. Here we can see the lower left container does not preserve the 3d space into its children, while the upper right container does.

preserve-3d.css
.parent {
    transition: transform 0.4s ease;
    transform-style: preserve-3d;
    perspective: 600px;
    transform: rotateX(0) rotateY(0) rotateZ(0);
}
.parent[data-toggle="true"] {
    transform-style: preserve-3d;
    transform: rotateX(70deg) rotateY(-10deg) rotateZ(50deg);
    .child {
        transform: translateZ(40px);
    }

    .child[data-3d="true"] {
        transform-style: preserve-3d;
    }

    .grandchild {
        transform-style: preserve-3d;
        transform: translateZ(30px);
    }
}

.child {
    /* NOTE NO PRESERVE 3D TRANSFORM,
    SO THE GRANDCHILDREN WILL NOT
    RENDER WITH 3D EFFECTS */
    transition: transform 0.4s ease;
    transform: translateZ(0);
}
.grandchild {
    transition: transform 0.4s ease;
    transform: translateZ(0);
}
3d
Not 3d