CSS fixed 定位元素失效的问题
CSS fixed 定位元素失效的问题
一个示例
考察下面的代码:
<head>
<title>css filter issue</title>
<style>
body {
height: 200vh;
background: #ddd;
}
.container {
background: grey;
height: 200px;
}
.fixed {
color: red;
position: fixed;
top: 0;
right: 0;
}
</style>
</head>
<body>
<div class="container">
<div class="fixed">fixed item</div>
</div>
</body>
页面中有一个位于右上角 position: fixed
定位的元素。按照预期,在页面滚动时它将固定在那个位置。
正常的 fixed 元素其表现
现在对容器加应用 CSS filter
样式,
.container {
+ filter: invert(1);
background: grey;
height: 200px;
}
再观察结果,注意到 fixed
元素不再 fixed
了。
fixed 元素不再生效
原因
根据 W3C 对 filter
的描述:
A value other than none for the filter property results in the creation of a containing block for absolute and fixed positioned descendants unless the element it applies to is a document root element in the current browsing context. The list of functions are applied in the order provided.
对于指定了 filter
样式且值不为 none
时,被应用该样式的元素其子元素中如果有 position
为 absolute
或 fixed
的元素,会为这些元素创建一个新的容器,使得这些绝对或固定定位的元素其定位的基准相对于这个新创建的容器。
相同的情况对 transform
也适用,以下是 W3C 规范的描述:
In the HTML namespace, any value other than none for the transform results in the creation of both a stacking context and a containing block. The object acts as a containing block for fixed positioned descendants.
解决
这里只看 filter
的修复。条件允许的情况下,有如下两种方式。
将 filter
应用到根节点
因为根据规范中对 filter
的描述,如果 filter
应用到根节点,则不会创建新的容器。所以可以将 filter
样式写到 html
,如果条件允许的话。
html{
filter: invert(1);
}
将 `filter` 应用到根节点后的修复
将 filter
应用到非正常定位的元素上
对于 filter
样式,还可以将其只应用到出问题的这些非正常定位的元素身上来解决。
.fixed {
+ filter: invert(1);
color: red;
position: fixed;
top: 0;
right: 0;
}
将 `filter` 应用到固定定位的元素本身身上