Preserving Three Dimensions with transform-style in CSS

As you work with 3D transforms, you may stumble across a scenario in which your transforms fail to work—or they work, but only for one element. This is caused by grouping property values . Some combinations of CSS properties and values require the browser to flatten the representation of child elements before the property is applied. These include opacity when the value is less than 1 and overflow when the value is something other than visible .

Here’s the counterintuitive part: transform and perspective also trigger this flattening when their value is something other than none . In effect, this means that child elements stack according to their source order if they have the same z-index value, regardless of the transform applied. Consider the following source:

<div class=”wrapper”>

<figure>a</figure>

<figure>f</figure>

</div>

And the following CSS:

.wrapper {

perspective: 2000px;

perspective-origin: 50% -200px;

}

.wrapper figure {

position: absolute;

top: 0; width: 200px;

height: 200px;

}

.wrapper figure:first-child {

transform: rotateY(60deg) translateZ(191px);

background: #3f51b5;

}

.wrapper figure:nth-child(2) {

transform: rotateY(120deg) translateZ(191px);

background: #8bc34a;

}

In this example, since we’ve applied perspective: 1000px to .wrapper , our <figure> elements are flattened. Since both elements also have the same calculated z-index , .wrapper figure:nth-chiLd(2) will be the topmost element in the stack, as seen in the following image.

Note that .wrapper figure:first-chiLd is still visible. It’s just not the topmost element. Here the computed value of transform-styLe is flat .

To work around this, we set the value of transform-style to preserve-3d . Let’s update our CSS:

.wrapper {

perspective: 2000px;

perspective-origin: 50% -200px;

transform-style: preserve-3d;

}

.wrapper figure {

position: absolute;

top: 0;

width: 200px;

height: 200px;

}

.wrapper figure:first-child {

transform: rotateY(60deg) translateZ(191px);

background: #3f51b5;

}

.wrapper figure:nth-child(2) {

transform: rotateY(120deg) translateZ(191px);

background: #8bc34a;

}

Now .wrapper figure:first-chiLd becomes the topmost element, as our rotateY() functions suggest it should be in the image below.

In the vast majority of cases, you should use transform-styLe: preserve-3d . Use transform- styLe: flat only when you want to collapse child elements into the same layer as their parent.

Source: Brown Tiffany B (2021), CSS , SitePoint; 3rd edition.

Leave a Reply

Your email address will not be published. Required fields are marked *