position:fixed会一直依据窗口进行定位吗
2022-07-25 本文已影响0人
前端辉羽
在刚开始学习CSS的时候,我们都知道固定定位:
固定定位(position:fixed;)其实是绝对定位定位的子类别,一个设置了position:fixed 的元素相对于视窗是固定的,就算页面文档发生了滚动,它也会一直待在相同的地方
但是在实际项目中却遇到了明明使用了fixed定位,但该元素却没有按照期望基于屏幕视口(viewport),而是依据了它的祖先元素。
image.png
排查原因,发现该元素定位依赖的祖先元素设置了transform属性,尝试去除该属性,fixed定位恢复正常。
查阅了相关文档,发现transform属性确实是有副作用的:
- transform 的元素会影响overflow area (溢出区域)。也就是说,使用transform使得元素移出了父元素之外的话,在父元素上使用overflow: scroll和overflow:auto的情况下,父元素将会展示出滚动条。
- transform 的元素会创造一个stack context (层叠上下文),造成内部和外部的z-index相互独立。
- transform 的元素将会创建一个 containing block (包含块),所有的position为absolute和fixed的子元素、以及设置了background-attachment的背景将会相对于该元素的 padding box 布局。
第三条即造成fixed失效的原因;是由于transform元素创建了一个Containing Block —— 它是元素渲染的一个基本概念,会影响元素的布局。
W3C规范里也找到了对应的解释:
transform 值不为 none 的元素会创建一个 containing block,然后该元素的 fixed 子元素会相对该元素进行定位
transform是一个很好用的属性,不可能弃之不用,那如果规避这种冷门BUG的发生呢?
加入我们想要对某个元素进行fixed定位,那么我们应该将这个元素放在页面的根元素之下,这样只要不对根元素进行过多的样式操作,就不会产生这个问题