anjia / blog

博客,积累与沉淀
106 stars 4 forks source link

看图理解 perspective 和 preserve-3d #56

Open anjia opened 5 years ago

anjia commented 5 years ago

今天和大家分享两个和 CSS 3D 相关的属性/值:

为什么要分享它们两个呢?最近在 100dayscss 上做 CSS 题的时候,被下面这个效果给难住了。

当时鬼使神差地就是不知道如何把图 1.1 变成图 1.2。

图 1.1 图 1.2

后来偷偷作弊了下,才知道是漏了transform-style: preserve-3d。和 3D 密切相关的还有一个perspective属性,故本文重点介绍下这两个。

perspective

perspective属性决定了z=0平面和用户眼睛之间的距离,当绘制 3D 的时候会用到。

先来看个例子:立方体,宽 100px 高 100px,其中心点在坐标系的原点(0,0,0)处。

立方体的中心点在(0,0,0),所以z=0平面也在立方体的中心点位置

下表是不同perspective下的效果(在线预览):

perspective:0px perspective:50px perspective:51px perspective:100px
图 2.1 图 2.2 图 2.3 图 2.4

说明:

注意:

perspective的值可以是none<length> 当值是 0 或者负数时,则不会有 3D 效果

transform-style

transform-style 属性决定了元素的子元素是在 3D 空间中展开,还是在 2D 平面中展开。

注意:

这个概念比较好理解。我们直接以开头的例子为例:

每小片rotateX(-24deg) 父容器未设置 3d 父容器设置了transform-style:preserve-3d
图 3.1 图 3.2 图 3.3

说明:

目前伞整体是往里扣着的,现在,我们把它再转过来。即给伞的父容器设置:

transform: rotateX(70deg) rotateY(-15deg);  /* 前后翻转个角度,再倾斜下 */
transform-style: preserve-3d;    /* 需要是 3d 上下文 */

最终的效果就实现了:

完整代码,可点击在线预览

主要参考

https://drafts.csswg.org/css-transforms-2/#propdef-perspective https://drafts.csswg.org/css-transforms-2/#transform-style-property

jiyuzhuang commented 5 years ago

支持一下

anjia commented 5 years ago

transform-style

Name: transform-style Value: auto | flat | preserve-3d Initial: auto

来自 CSS Transforms Module Level 2(在大多数浏览器里,就两个值 flat | preserve-3d,无 auto

transform-styleflat值会创建堆叠上下文,并建立 3D 渲染上下文。在进行 3D 渲染计算时,会忽略值是auto的元素,而值是preserve-3d的元素会把这个 3D 渲染上下文扩展到它们所属的 3D 上下文里(即使 transformperspective 属性的值会导致 2D 平面化)。值preserve-3d会创建堆叠上下文,并为所有后代元素创建一个包含块。

两个概念:

  • 3D 渲染上下文:即有共同祖先的一组元素,它们会共享相同的三维坐标系
  • 另外,transform属性,只要它的值不是none,它就会触发元素为所有的后代建立一个包含块,元素的 padding box 将用于布局所有的绝对定位、fix 定位的后代元素,和后代的 fixed background attachments。