为什么在父级上应用 CSS-Filter 会破坏子级定位?
所以我有这个标题屏幕动画";标题居中在全屏页面上,当您向下滚动时,它会变小并保持在页面顶部.这是一个具有预期行为的工作示例,我从中删除了所有不必要的代码以使其最小化:
So I have this title-screen "animation" that has the title centered on a fullscreen page and when you scroll down it becomes smaller and remains at the top of the page. Here is a working example with the expected behavior, from which I stripped all unnecessary code to make it minimal:
$(window).scroll( () => {
"use strict";
let windowH = $(window).height();
let windowS = $(window).scrollTop();
let header = $("#header").height();
if (windowS < windowH-header) {
$("#title").css("transform", "scale("+(2-(windowS/($(document).outerHeight()-windowH))*2.7)+")");
$("#header").css("transform", "translateY(0)");
$("#inside, #content").css({
"position": "static",
"margin-top": 0
});
} else {
$("#inside").css({
"position": "fixed",
"margin-top": -windowH+header
});
$("#content").css("margin-top", windowH);
}
$("#header").css("position", windowS > (windowH-header)/2 ? "fixed" :"static");
});
.fixed {
position: fixed!important;
}
.wrapper {
width: 100%;
text-align: center;
}
.wrapper:before {
display: table;
content: " ";
}
.wrapper:after {
clear: both;
}
#inside {
width: 100%;
height: 100vh;
background-color: lightcoral;
display: flex;
align-items: center;
justify-content: center;
}
#header {
height: 90px;
top: 0;
position: sticky;
display: flex;
align-items: center;
justify-content: center;
transition: all 0.5s;
}
#title {
width: 100%;
color: #fff;
transform: scale(2);
}
#content {
height: 1000px;
background-color: lightblue;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<body>
<div class="wrapper">
<div id="inside">
<div id="header">
<h1 id="title">Title</h1>
</div>
</div>
<div id="content"></div>
</body>
接下来是完全相同的片段,但添加了一个:我应用了一个过滤器,就我而言,它纯粹是装饰性的:filter:brightness(1.3);
.
Next up is the exact same snippet but with one addition: I applied a filter, which is, as far as I'm concerned, purely cosmetic: filter: brightness(1.3);
.
正如您在动画"中滚动到一半时所看到的那样.标题就消失了.当您检查元素时,它仍然具有所有属性,但不知何故它消失了.这在 Firefox 和 Chrome 中是一样的,我不知道为什么.如果有人可以发布一个应用了过滤器的工作片段并解释为什么它以前不起作用,我将不胜感激.
As you can see below when you scroll half-way through the "animation" the title just disappears. When you inspect the element it still has all its properties but somehow it's gone. This is the same in Firefox and Chrome and I have no idea why. I would appreciate it a lot if someone could post a working snippet with the filter applied and explain why it didn't work before.
$(window).scroll( () => {
"use strict";
let windowH = $(window).height();
let windowS = $(window).scrollTop();
let header = $("#header").height();
if (windowS < windowH-header) {
$("#title").css("transform", "scale("+(2-(windowS/($(document).outerHeight()-windowH))*2.7)+")");
$("#header").css("transform", "translateY(0)");
$("#inside, #content").css({
"position": "static",
"margin-top": 0
});
} else {
$("#inside").css({
"position": "fixed",
"margin-top": -windowH+header
});
$("#content").css("margin-top", windowH);
}
$("#header").css("position", windowS > (windowH-header)/2 ? "fixed" :"static");
});
.fixed {
position: fixed!important;
}
.wrapper {
width: 100%;
text-align: center;
}
.wrapper:before {
display: table;
content: " ";
}
.wrapper:after {
clear: both;
}
#inside {
width: 100%;
height: 100vh;
background-color: lightcoral;
filter: brightness(1.3); /*<<<<<<<<<<<<<<<<*/
display: flex;
align-items: center;
justify-content: center;
}
#header {
height: 90px;
top: 0;
position: sticky;
display: flex;
align-items: center;
justify-content: center;
transition: all 0.5s;
}
#title {
width: 100%;
color: #fff;
transform: scale(2);
}
#content {
height: 1000px;
background-color: lightblue;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<body>
<div class="wrapper">
<div id="inside">
<div id="header">
<h1 id="title">Title</h1>
</div>
</div>
<div id="content"></div>
</body>
推荐答案
如果我们参考 规范我们可以阅读:
If we refer to the specification we can read:
过滤器属性的值不是 none 会导致为绝对定位和固定定位创建一个包含块descendants 除非它适用的元素是文档根当前浏览上下文中的元素.函数列表是按提供的顺序应用.
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.
这意味着您的 position:fixed
元素将相对于过滤后的容器定位,而不是视口.换句话说,它仍然是固定的,但在它的 new 包含块(过滤的容器)内
This means that your position:fixed
element will be positioned relatively to the filtered container and no more the viewport. In other words, it's still fixed but inside its new containing block (the filtered container)
这里有一个简化的版本来说明这个问题:
Here is a simplified version to illustrate the issue:
.container {
display: inline-block;
width: 200px;
height: 200vh;
border: 1px solid;
}
.container>div {
position: fixed;
width: 100px;
height: 100px;
background: red;
color: #fff;
}
<div class="container">
<div>I am fixed on scroll</div>
</div>
<div class="container" style="filter:grayscale(1);">
<div>I move with the scroll</div>
</div>
要解决此问题,请尝试将过滤器移动到固定元素而不是其容器:
To fix the issue try to move the filter to the fixed element instead of its container:
.container {
display: inline-block;
width: 200px;
height: 200vh;
border: 1px solid;
}
.container>div {
position: fixed;
width: 100px;
height: 100px;
background: red;
color: #fff;
filter: grayscale(1);
}
<div class="container">
<div>I am fixed on scroll</div>
</div>
这是一个非详尽的1属性列表,导致为绝对和固定定位的后代创建包含块
Here is a non-exhaustive1 list of the properties that results in the creation of a containing block for absolute and fixed positioned descendants
过滤器
transform
参考backdrop-filter
refperspective
ref包含
reftransform-style
参考内容可见性
refwill-change
与上述值之一一起使用时
filter
transform
refbackdrop-filter
refperspective
refcontain
reftransform-style
refcontent-visibility
refwill-change
when used with one of the above values
如果属性的任何非初始值会导致元素为绝对定位元素生成包含块,则在 will-change 中指定该属性必须导致元素为绝对定位元素生成包含块.参考
If any non-initial value of a property would cause the element to generate a containing block for absolutely positioned elements, specifying that property in will-change must cause the element to generate a containing block for absolutely positioned elements. ref
1:我会尽量保持这个列表是最新的.
1: I will try to keep this list up to date.
相关文章