父母的CSS过滤器破坏了孩子的位置

leo*_*ess 10 css css-position css3 css-transforms css-filters

我目前正在网站上,遇到这种奇怪的行为。我不确定这是一个错误还是如何解决它,所以我想向您寻求帮助。

因此,我有这个标题屏幕的“动画”,该标题的标题位于全屏页面的中央,当您向下滚动时,标题变小并保留在页面顶部。这是一个具有预期行为的工作示例,从中我剥离了所有不必要的代码以使其最小化:

$(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");
});
Run Code Online (Sandbox Code Playgroud)
.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;
}
Run Code Online (Sandbox Code Playgroud)
<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>
Run Code Online (Sandbox Code Playgroud)

接下来是完全相同的代码段,但有一个附加代码段:我应用了一个过滤器,就我而言,这纯粹是装饰性的:filter: brightness(1.3);

正如您在下面看到的那样,当您滚动到“动画”的一半时,标题消失了。当您检查元素时,它仍然具有其所有属性,但是不知何故消失了。在Firefox和Chrome中是相同的,我也不知道为什么。如果有人可以发布一个应用了过滤器的有效代码段并解释为什么以前不起作用,我将不胜感激。

$(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");
});
Run Code Online (Sandbox Code Playgroud)
.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;
}
Run Code Online (Sandbox Code Playgroud)
<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>
Run Code Online (Sandbox Code Playgroud)

Tem*_*fif 9

如果我们参考规范,我们可以阅读:

过滤器属性的非空值将导致为绝对定位和固定定位的 后代创建一个包含块,除非其所应用的元素是当前浏览上下文中的文档根元素。功能列表按提供的顺序应用。

这意味着您的position:fixed元素将相对于过滤后的容器而不是视口放置。换句话说,它仍然是固定的,但是在其新的包含块(过滤容器)中

这是一个简化的版本来说明此问题:

.container {
  display: inline-block;
  width: 200px;
  height: 200vh;
  border: 1px solid;
}

.container>div {
  position: fixed;
  width: 100px;
  height: 100px;
  background: red;
  color: #fff;
}
Run Code Online (Sandbox Code Playgroud)
<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>
Run Code Online (Sandbox Code Playgroud)

要解决此问题,请尝试将过滤器移至固定元素而不是其容器:

.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);
}
Run Code Online (Sandbox Code Playgroud)
<div class="container">
  <div>I am fixed on scroll</div>
</div>
Run Code Online (Sandbox Code Playgroud)


它的行为与transform完全相同:“ transform3d”不适用于位置:固定子级

  • 谢谢!我仍然想知道为什么会这样。如果不是这样不是更好吗? (4认同)
  • 您的答案的进一步说明:[此GitHub问题](https://github.com/w3c/fxtf-drafts/issues/11)添加了以下规范:当`filter`具有除`none'以外的其他值时,将创建一个包含块`。GitHub问题也有一个讨论的链接,该讨论是在此决定的,并且[此代码示例](http://fiddle.jshell.net/mkud1Lnm/1/)([存档链接](https://web.archive .org / web / 20160405103427 / http://fiddle.jshell.net/mkud1Lnm/1/))来说明包含块旨在修复的歧义。 (4认同)