Understanding the z-offset in transform-origin

2020-04-11 06:43发布

I am trying to study the transform origin property and how exactly this property works. I have made a small demo HERE.

HTML:

<div class="section-title">
        <span data-hover="Product Range">Product Range</span>
    </div>

CSS :

.section-title {
                text-align: center;
                margin: 50px 0px;
                color: #FFF;
                text-transform: uppercase;
                perspective: 1000px;
            }

            .section-title span {
                font-size: 2em;
                position: relative;
                display: inline-block;
                padding: 0px 14px;
                background: #2195DE none repeat scroll 0% 0%;
                transition: transform .3s ease 0s;
                transform-origin: 50% 0px 0px;
                transform-style: preserve-3d;
            }

            .section-title span::before {
                position: absolute;
                top: 100%;
                left: 0px;
                width: 100%;
                height: 100%;
                background: #0965A0 none repeat scroll 0% 0%;
                content: attr(data-hover);
                transition: #000 .3s ease 0s;
                transform: rotateX(-90deg);
                transform-origin: 50% 0;
                text-align: center;
            }

            .section-title span:hover, .section-title span:focus {
                transform: rotateX(90deg) translateY(-22px);
            }

            .section-title span:hover::before, .section-title span:focus::before {
                background: #28A2EE none repeat scroll 0% 0%;
            }

Now if you have a look at the transform-origin property it had the following definition in the stylesheet:

transform-origin: 50% 0 0;

I changed it to:

transform-origin: 50% 0;

and saw no difference. My problem is understanding the z-axis property value in the transform-origin property and what VISUAL difference there is without it .

MDN has the following definition for z-axis property:

z-offset::

Is a (and never a which would make the statement invalid) describing how far from the user eye the z=0 origin is set.

but in spite of the definition, I fail to understand or re-create any such example in which the z-offset makes any visual difference.

Can somebody here please help me understand of what significance is the z-offset in tranform-origin? can somebody provide a visual example of what the z-offset does?

1条回答
The star\"
2楼-- · 2020-04-11 07:11

First, the z-offset value for transition-origin only works on 3D transforms. Luckily, you have one in your fiddle, but it seems like the only value you tried was zero (the default value); not entering a value is the same as entering 0, the default. Think of it as the same principle as the z-index: you're telling it how close to the screen it needs to be.

There's an important caveat: values in z-offset are reversed from z-index (as well as translateZ). A higher z-index will move items closer to the screen (since the stacking context starts at 0 and higher stacking levels bring you closer to the screen), but a higher z-offset moves the element's origin farther away (since the z-offset is describing how far away an element's transform-origin should be, higher z-offset values = farther away).

So to understand the 3D graph, consider these axes from the point of view of the z axis ray moving directly toward us.

3D axes

Looking at this graph, setting a z-offset of -38px would move an element's transform-origin point a little closer to us. Inversely, a z-offset of 38px would move the transform-origin point a little farther away.

In this example, however, the span element has already been rotated -80 degrees (I picked 80 instead of 90 so that you can see the rotation a bit easier) along the X axis. This is done first, since 3D Transforms are cumulative, so each transform is done in order, step-by-step (this also means that transforms of parents are inherited by their children). So really, the graph above can now be considered rotated as well, with the z-axis ray pointing down, and the y-axis ray pointing away from us.

Let's take your example and change the z-offset of the additional face to -38px (the length (its height, in CSS terms) of the face that is initially visible) to see how it moves farther away from its origin point. Considering the z-axis ray was pointing down after we applied RotateX(-80deg), that means the z-offset element should move down (since negative z-offset values mean "move closer") to the bottom of the viewport.

.section-title {
    text-align: center;
    margin-top: 50px;
    color: #FFF;
}
.section-title span {
    font-size: 36px;
    position: relative;
    display: inline-block;
    padding: 0px 14px;
    background: #2195DE;
    transition: transform .5s ease;
    transform-style: preserve-3d;
}
.section-title span::before {
    position: absolute;
    top: 100%;
    left: 0px;
    width: 150px;
    height: 100%;
    background: #2195DE;
    content: "test";
    transform: rotateX(-80deg);
    transform-origin: 0px 0px -38px;
    text-align: center;
    
}
.section-title span:hover {
    transform: rotateX(80deg);
}
.section-title span:hover::before {
    transform-origin: 0px 0px 0px;
}
<div class="section-title">
    <span>Product Range</span>
</div>

Now the z-offset face (created with ::before) has moved closer to the bottom of the viewport. This means it would be 38px (since each side is 38px long) closer to the screen if we hadn't rotated it 80 degrees already. I re-set it back to 0px on hover, so it snaps back to normal position, as you can see by hovering.

This property is useful for creating 3D transforms of typically 3D elements. The most obvious choice is a six-sided die. You would use the z-offset to create the back side of the die (along with backface-visibility: hidden; so that we don't see through the element).

查看更多
登录 后发表回答