transform 的副作用

本文作者:IMWeb elvin 原文出处:IMWeb社区 未经同意,禁止转载

transform 想必大家都很熟悉,可以通过其转换(translate)、旋转(rotate)、缩放(scale)、倾斜(skew)等属性来对元素进行变换,不过这篇文章想探讨的不是这些内容,而是 transform 对元素布局、页面渲染方面的影响。例如,你知道它会影响 fixed 元素的位置吗?你有想过它会改变元素的层叠顺序吗?

tranform 改变 fixed 子元素的定位对象

例子探究

首先我们来看一个例子(代码在这里):下面示例中的 fixed 元素设置的是 top: -50px,按理说我们应该是看不见它的,因为它会相对根元素定位到页面上方的外部。然而事实狠狠打了我们的脸,它是可见的!这是为什么呢?

关键就在于这个 fixed 元素被拥有 transform 的属性的父 div 包裹着,所以它会相对于这个 transform 的父元素定位,而不是我们以为的根元素定位,又由于父元素有 margin-top: 50px 的值,所以两者相抵消(-50px + 50px = 0),最终导致该元素位于页面起始处。

至于为什么会这样,就需要从 W3C 规范中去寻找原因了。在 W3C - transform rendering 中,我找到了这样一段解释:For elements whose layout is governed by the CSS box model, any value other than none for the transform also causes the element to become a containing block, and the object acts as a containing block for fixed positioned descendants,也就是说 transform 值不为 none 的元素会创建一个 containing block(作者注:容器块,盒元素定位和大小一般参考容器块进行计算),然后该元素的 fixed 子元素会相对该元素进行定位。

一点思考

原因搞明白了,那么为什么 W3C 委员会会这样设计呢?依我愚见,可以从两个方面来思考:

  1. 假如我们想让 fixed 元素 相对根元素进行绝对定位,我们往往会把它作为根元素的第一级子元素,从而也就不会存在它被 transform 父元素 包裹的情况了。
  2. 那么什么情况下我们会把 fixed 元素 放在 transform 父元素 下呢?在我看来,只有我们希望它跟随父元素一起变形时才会这样做,要不然为什么不把它放在根元素下呢?

transform 改变元素层叠顺序

例子探究

同样的,我们先来看一个例子(代码在这里):下面示例中第一行为啥都没加的情况下,让第二个元素(蓝色块)通过 margin-left: -40px 向左偏移了 40px,按照后来居上的层叠规则,它会盖住第一个元素(黄色块)的一部分。第二行给第一个元素(黄色块)加上了 transform: scale(1) 后一切就变了,它盖住了第二个元素(蓝色块),后来居上的规则貌似不起作用了,这是为什么呢?

同样的,还是尝试从 W3C 规范中去寻找原因。在 W3C - transform rendering 中,我找到了一句和上一节基本一样的一句话:For elements whose layout is governed by the CSS box model, any value other than none for the transform results in the creation of a stacking context,也就是说 transform 值不为 none 的元素会创建一个 stacking context(层叠上下文)。层叠上下文,这是什么鬼?好像只听过块级格式化上下文(BFC)。

简单说来,层叠上下文与元素在 z 轴上的展示顺序相关,而且层叠上下文元素的层叠水平要比普通元素高,结合上面的例子来说就是:

  1. 根元素是层叠上下文元素,蓝色块和黄色块都是它的子元素;
  2. 蓝色块由于 transform 值不为 none ,所以升级为层叠上下文元素,因而它的层叠水平比黄色块(普通元素)高。

层叠上下文的内容值得深入地具体探究,这里推荐两个不错内容,一个是 MDN - 层叠上下文,另外一个则是 张鑫旭 - 深入理解CSS中的层叠上下文和层叠顺序

写在最后

当使用 CSS 遇到奇奇怪怪问题的时候,我们既可以在 Google 或者 StackOverflow 上寻找答案,也不要忘了 W3C 的存在。有时真相其实早已静静地躺在标准当中,只要我们肯于寻找、善于寻找,定能找到 ^_^

参考链接

  1. W3C- CSS Transforms Module Level 1
  2. 张鑫旭 - CSS3 transform对普通元素的N多渲染影响
  3. 张鑫旭 - 深入理解CSS中的层叠上下文和层叠顺序
  4. 结一老师 - 视觉格式化模型 - 容器块

博客原文链接

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏GIS讲堂

Arcgis for JS之Cluster聚类分析的实现(基于区域范围的)

咱们书接上文,在上文,实现了基于距离的空间聚类的算法实现,在本文,将继续介绍空间聚类之基于区域范围的实现方式,好了,闲言少叙,先看看具体的效果:

1495
来自专栏天天

background、转换、过渡

1003
来自专栏阿凯的Excel

巧妙完成二维表的数据匹配

接下来我将每周分享一个广大网友向我提问的经典问题。 本周问题,如何对二维表进行匹配! 原表格! ? 备注:以上人名,均属虚构,如有雷同!说明有缘!!! 咳...

2823
来自专栏HT

基于HT for Web的3D树的实现

在HT for Web中2D和3D应用都支持树状结构数据的展示,展现效果各异,2D上的树状结构在展现层级关系明显,但是如果数据量大的话,看起来就没那么直观,找到...

2025
来自专栏HT

基于HT for Web的3D拓扑树的实现

在HT for Web中2D和3D应用都支持树状结构数据的展示,展现效果各异,2D上的树状结构在展现层级关系明显,但是如果数据量大的话,看起来就没那么直观,找到...

2315
来自专栏数据小魔方

一款脑洞大开的表格可视化神器

今天跟大家介绍一款任坤大神写的新包——formattable。 这个包的功能很简单,但是却很具创意性,它颠覆了R语言data.frame数据表的呈现方式,允许在...

4848
来自专栏前端新视界

使用 SVG 和 JS 创建一个由星形变心形的动画

序言:首先,这是一篇学习 SVG 及 JS 动画不可多得的优秀文章。我非常喜欢 Ana Tudor 写的教程。在她的教程中有大量使用 SVG 制作的图解以及实...

6315
来自专栏HT

基于HTML5的3D网络拓扑树呈现

在HT for Web中2D和3D应用都支持树状结构数据的展示,展现效果各异,2D上的树状结构在展现层级关系明显,但是如果数据量大的话,看起来就没那么直观,找到...

25410
来自专栏逍遥剑客的游戏开发

M2文件头

1192
来自专栏林德熙的博客

win10 uwp win2d 使用 Path 绘制界面

在 win2d ,可以使用 DrawGeometry 的方式画出几何。而路径 Path 就是一种 Geometry 。传入的 CanvasGeometry 参数...

1241

扫码关注云+社区

领取腾讯云代金券