使用transform带来的影响

在CSS3中,transform 属性可以向元素应用 2D 或 3D 转换。我们可以对元素进行旋转、缩放、移动等操作,其中我经常用它的translate属性来实现元素的水平垂直居中。
在使用过程中,发现了一些预期的样式会被transform所混淆。比如会影响到元素的垂直定位,fixed定位等等……

1、position: fixed没有相对于窗口定位

html:

<div class="box">
    <div class="box-content">
        <h1>box</h1>
        <button class='btn'>button</button>
    </div>
</div>

​ css:

.box-content {
    position: absolute;
    border: 1px solid red;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
}
.btn {
    position: fixed;
    top: 0px;
}

我们知道,position为fixed的元素定位是相对于窗口的,当窗口出现滚动条时,元素也能保证距离窗口的位置不变,不会随着滚动条的滚动而滚动。

在一个居中的弹框里,我想要让某个子元素有fixed效果,但是意外的是它没有根据窗口定位,而是根据居中弹框进行定位。在去除弹框的transform属性后,子元素才相对于窗口定位,这是因为父元素的transform属性会使子元素的fixed定位表现出absolute定位!因此滚动条滚动会改变元素的定位。但即使是absolute定位,元素会相对于transform元素定位,不会相对于第一个非static定位的父元素定位!


此外,除了transform会干扰到fixed定位外,设置filter模糊属性也会影响fixed定位。

2、transform影响元素的垂直定位

在传统的css中,z-index必须配合定位元素才能生效。一说到垂直方向的定位,我们就会联想到z-index,但实际上垂直方向的定位还与层叠上下文有关,且遵循层叠顺序规则。
html:

<div class="ele1">111</div><div class="ele2">222</div>

​ css:

.ele1 {
    background-color: red;
    display: inline-block;
    width: 50px;
    /* transform: scale(1); */
}
.ele2 {
    background-color: green;
    display: inline-block;
    width: 50px;
    margin-left: -10px;
}

由于ele2向左产生了负边距,因此在垂直方向上和ele1产生重叠。又因为“先来后到”原则,ele2会覆盖到ele1上面。但是如果ele1元素上应用了transform属性,就会产生相反的效果。

这是是因为tranform会让元素变为层叠上下文元素,在没有z-index属性时,层叠上下文元素会比普通元素的层叠顺序更高!因此会覆盖掉普通元素。如下图所示:
Image text
可以看到,不依赖z-index的层叠上下文元素在z轴上是高于inline-block元素的!关于层叠上下文,我正在学习中,具体学习掌握后会再分享给大家!

3、transform影响绝对元素的溢出

overflow与绝对元素之间有这样一个限制:如果有一个absolute绝对定位元素,含有overflow不为visible的父级元素,同时,该父级元素以及到该绝对定位元素之间任何嵌套元素都没有position为非static属性的声明,则overflow对该absolute元素不起作用。

<div class="container" style="width: 150px; overflow: hidden;">
    <p>
        <span style="position: absolute; width: 200px; background: red;">element</span>
    </p>
</div>


如果父元素添加transform属性,那么绝对元素会受到父元素溢出的影响。

<div class="container" style="width: 150px; overflow: hidden;transform: scale(1);">
    <p>
        <span style="position: absolute; width: 200px; background: red;">element</span>
    </p>
</div>

4、transform影响绝对元素的百分比设置

我们知道,绝对元素设置样式百分比,是根据第一个非static定位的父元素进行定位的,否则就会根据根元素定位。但是如果绝对元素的某个祖先元素上设置了transform属性,那么绝对元素会相对于这个元素进行定位!

<div class="container" style="width: 150px;/* transform: scale(1); */">
    <p>
        <span style="position: absolute; width: 100%; background: red;">element</span>
    </p>
</div>


可以看到,上面图片的绝对元素宽度是根据窗口计算的;下面图片的绝对元素宽度是根据设置了transform的元素而计算的。

此外,transform还会导致字体在动画时候变模糊等等。因此,在css编写中,不应该滥用transform,又或者说能够明白transform的使用可能造成的影响。

关于 “使用transform带来的影响” 的 5 个意见

  1. 棒棒的,言必行行必果~
    之前我就遇到过你说的问题。页面底部有一个fixed的bar,同时又有一个可以滑动出来的侧边栏(transform)。发现滑动侧边栏回来后,滚动页面时fixed的bar变成了类似absolute的样式,会随着页面滚动。

发表评论