Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Open
anjia opened this issue Mar 18, 2019 · 2 comments
Open

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

anjia opened this issue Mar 18, 2019 · 2 comments
Labels
CSS cascading style sheets 文章

Comments

@anjia
Copy link
Owner

anjia commented Mar 18, 2019

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

  • 属性 perspective
  • 声明 transform-style: preserve-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:0px时,纯平面,没有 3D 效果
  • perspective:50px时,刚好是立方体的中心位置
  • perspective:51px时,粉红色的“1号”面刚漏出1px,故相比之前的图,方位变化不大,但是颜色偏红
  • perspective:100px时,立方体整个都视线之内

注意:

  • 3D 元素在用户后面的部分是不会被绘制的(如图 2.2、2.3)
  • 消失点默认是元素的中心位置。我们也可以通过perspective-origin属性来设置

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

transform-style

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

  • transform-style: flat 元素的子元素们是放置在元素本身的平面中的
  • transform-style: preserve-3d 元素的子元素们是放置在 3D 空间中的

注意:

  • 如果值是flat,则元素的子元素们将不会在它们自己的 3D 空间中存在
  • transform-style是不能被继承的,这就意味着如果元素的非叶子后代需要在 3D 中展开,则必须给子元素自己也设置下

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

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

说明:

  • 图 3.2 里,伞片之所以比容器小,是因为伞片沿 X 轴旋转了
  • 图 3.3 里,大小又比 3.2 看起来小了点,是因为父容器设置了 3d,导致伞“往里扣”了,所以再小了点

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

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
Copy link

支持一下

@anjia anjia added CSS cascading style sheets 文章 labels Mar 19, 2019
@anjia
Copy link
Owner Author

anjia commented Mar 19, 2019

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。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
CSS cascading style sheets 文章
Projects
None yet
Development

No branches or pull requests

2 participants