CSS 3d transform doesn't work if perspective is set in the end of property

左心房为你撑大大i 提交于 2019-11-28 02:07:02

You should make the perspective first in both cases. If you add it at the end the translation will be first made without considering the perspective.

If we refer to the specification we can see how the transformation matrix is computed:

The transformation matrix is computed from the transform and transform-origin properties as follows:

  1. Start with the identity matrix.

  2. Translate by the computed X and Y of transform-origin

  3. Multiply by each of the transform functions in transform property from left to right

  4. Translate by the negated computed X and Y values of transform-origin

As you can see in the step (3), it's from left to right (here is another question where you can get more information and see why order is important: Simulating transform-origin using translate)

It also useless to use the perspective property within the element you want to transform.

box:nth-child(1):hover {
  transform: perspective(1000px) translate3d(0, 0, -100px);
}

box:nth-child(2):hover {
  transform: perspective(1000px) translate3d(0, 0, 100px);
}

box {
  padding: 20px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font-family: monospace;
  transition: transform .4s;
  background: rgba(255, 0, 0, 0.3);
  margin: 20px;
  /*perspective: 1000px;*/
  font-size: 12px;
  cursor: pointer;
}

box:nth-child(2) {
  background: rgba(0, 0, 255, 0.3);
}
<box>
  transform: perspective(1000px) translate3d(0,0,100px);
</box>
<box>
  transform:  perspective(1000px) translate3d(0,0,100px);
</box>

To avoid any confusion with order you can declare the persepective within a parent element BUT you need to pay attention to the origin as it won't be the same:

box:nth-child(1):hover {
  transform:translate3d(0, 0, -100px);
}

box:nth-child(2):hover {
  transform:translate3d(0, 0, 100px);
}
body {
  perspective:1000px;
}
box {
  padding: 20px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font-family: monospace;
  transition: transform .4s;
  background: rgba(255, 0, 0, 0.3);
  margin: 20px;
  font-size: 12px;
  cursor: pointer;
}

box:nth-child(2) {
  background: rgba(0, 0, 255, 0.3);
}
<box>
  transform: perspective(1000px) translate3d(0,0,100px);
</box>
<box>
  transform:  perspective(1000px) translate3d(0,0,100px);
</box>
MatrixTai

Though another answer already give quite clear statement how perspective() works. But I want to make I bit more concrete.

box:nth-child(1):hover {
  transform: perspective(1000px) translate3d(0, 0, 100px);
}

box:nth-child(2):hover {
  transform: translate3d(0, 0, 100px) perspective(1000px);
}

box:nth-child(3):hover {
  transform: rotate3d(1, 0, 0, 45deg) perspective(1000px) translate3d(0, 0, 100px);
}

box:nth-child(4):hover {
  transform: rotate3d(1, 0, 0, 45deg) translate3d(0, 0, 100px) perspective(1000px);
}

box:nth-child(5):hover {
  transform: rotate3d(1, 0, 0, 45deg) translate3d(0, 0, 100px);
}

box:nth-child(6):hover {
  transform: translate3d(0, 0, 100px) rotate3d(1, 0, 0, 45deg);
}

box:nth-child(7):hover {
  transform: perspective(1000px) rotate3d(1, 0, 0, 45deg) translate3d(0, 0, 100px);
}

box:nth-child(8):hover {
  transform: perspective(1000px) translate3d(0, 0, 100px) rotate3d(1, 0, 0, 45deg);
}

box {
  padding: 20px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font-family: monospace;
  transition: transform .4s;
  background: rgba(255, 0, 0, 0.3);
  margin: 20px;
  font-size: 12px;
  perspective: 1000px;
  cursor: pointer;
}

box:nth-child(even) {
  background: rgba(0, 0, 255, 0.3);
}
<box>
  1. transform: perspective(1000px) translate3d(0,0,100px);
</box>
<box>
  2. transform: translate3d(0,0,100px) perspective(1000px);
</box>
<box>
  3. transform: rotate3d(1,0,0,45deg) perspective(1000px) translate3d(0, 0, 100px);
</box>
<box>
  4. transform: rotate3d(1,0,0,45deg) translate3d(0, 0, 100px) perspective(1000px);
</box>
<box>
  5. transform: rotate3d(1,0,0,45deg) translate3d(0, 0, 100px);
</box>
<box>
  6. transform: translate3d(0, 0, 100px) rotate3d(1,0,0,45deg);
</box>
<box>
  7. perspective(1000px) rotate3d(1,0,0,45deg) translate3d(0, 0, 100px);
</box>
<box>
  8. perspective(1000px) translate3d(0, 0, 100px) rotate3d(1,0,0,45deg);
</box>

First of all, for example 1 and 2. It is quite obvious showing how perspective() work for translate3d.

But is that mean without perspective(), translate3d is useless?

No. As I mentioned in the very first command.

without telling the browser the z-position of element, how can you do 3-dimensional translation?


But, how about 2-dimensional?

Take a look on example 3 and 5. They behave completely different.

Why? Because after you do the rotation, its z-dimension is no longer your windows' z-dimension. The block move upward as 100 * cos(45) = 50px.

And therefore, 5 and 6 work completely different, the order between rotate3d(1,0,0,45deg) and translate3d(0, 0, 100px) does make difference.

For 7 and 8 it is much more obvious when also the z-index becomes available for the element. It does difference.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!