transform
想必你们都很熟悉,能够经过其转换(translate)、旋转(rotate)、缩放(scale)、倾斜(skew)等属性来对元素进行变换,不过这篇文章想探讨的不是这些内容,而是 transform
对元素布局、页面渲染方面的影响。例如,你知道它会影响 fixed
元素的位置吗?你有想过它会改变元素的层叠顺序吗?css
首先咱们来看一个例子(代码在这里):下面示例中的 fixed 元素设置的是 top: -50px
,按理说咱们应该是看不见它的,由于它会相对根元素定位到页面上方的外部。然而事实狠狠打了咱们的脸,它是可见的!这是为何呢?html
关键就在于这个 fixed
元素被拥有 transform
的属性的父 div 包裹着,因此它会相对于这个 transform
的父元素定位,而不是咱们觉得的根元素定位,又因为父元素有 margin-top: 50px
的值,因此二者相抵消(-50px + 50px = 0),最终致使该元素位于页面起始处。css3
至于为何会这样,就须要从 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
子元素会相对该元素进行定位。web
缘由搞明白了,那么为何 W3C 委员会会这样设计呢?依我愚见,能够从两个方面来思考:segmentfault
fixed 元素
相对根元素进行绝对定位,咱们每每会把它做为根元素的第一级子元素,从而也就不会存在它被 transform 父元素
包裹的状况了。fixed 元素
放在 transform 父元素
下呢?在我看来,只有咱们但愿它跟随父元素一块儿变形时才会这样作,要否则为何不把它放在根元素下呢?一样的,咱们先来看一个例子(代码在这里):下面示例中第一行为啥都没加的状况下,让第二个元素(蓝色块)经过 margin-left: -40px
向左偏移了 40px,按照后来居上的层叠规则,它会盖住第一个元素(黄色块)的一部分。第二行给第一个元素(黄色块)加上了 transform: scale(1)
后一切就变了,它盖住了第二个元素(蓝色块),后来居上的规则貌似不起做用了,这是为何呢?ide
一样的,仍是尝试从 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)。wordpress
简单说来,层叠上下文与元素在 z 轴上的展现顺序相关,并且层叠上下文元素的层叠水平要比普通元素高,结合上面的例子来讲就是:布局
none
,因此升级为层叠上下文元素,于是它的层叠水平比黄色块(普通元素)高。层叠上下文的内容值得深刻地具体探究,这里推荐两个不错内容,一个是 MDN - 层叠上下文,另一个则是 张鑫旭 - 深刻理解CSS中的层叠上下文和层叠顺序。ui
当使用 CSS 遇到奇奇怪怪问题的时候,咱们既能够在 Google 或者 StackOverflow 上寻找答案,也不要忘了 W3C 的存在。有时真相其实早已静静地躺在标准当中,只要咱们肯于寻找、善于寻找,定能找到 ^_^.net