因此,我有一个标题屏幕“动画”,其中标题标题位于全屏页面的中心,当我向下滚动时,它会变小并停留在页面顶部。这是一个具有预期行为的工作示例,我从中删除了所有不必要的代码以保持最少:
$(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);
。
正如您在下面看到的,当您滚动“动画”一半时,标题就会消失。当您检查该元素时,它仍然保留其所有属性,但不知何故它不在那里。同样的事情发生在 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");
});
.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>
问题的免费翻译为什么将 CSS 过滤器应用于父元素会破坏子元素的定位?来自成员 @leonheess。
不幸的是,我无法回答为什么它会这样工作的问题(也许这是一个错误,或者是修复某些错误的功能)。我试图弄清楚,显然, 的块充当
filter
了一种relative
块,包括带有 的子块position:fixed
。尽管该块本身filter
具有position:static
.我尝试修复此代码,但行为不同
filter
PS 经过一番谷歌搜索后,我发现了更多以相同方式工作的属性。例如,
transform:translate(0,0)
它还将更改子绝对或固定元素的行为。如果您查看规范,您可以阅读:
Это означает, что ваш элемент
position:fixed
будет позиционироваться относительно фильтруемого контейнера, а не относительно области просмотра. Другими словами, он все ещеfixed
, но внутри нового содержащего блока (фильтрованного контейнера).Вот упрощенная версия, иллюстрирующая проблему:
Чтобы решить эту проблему, попробуйте переместить фильтр в фиксированный элемент, а не в его контейнер:
Вот неполный1 список свойств, который приводит к созданию содержащего блока для абсолютных и фиксированных потомков:
filter
transform
refbackdrop-filter
refperspective
refcontain
refcontainer
reftransform-style
refcontent-visibility
refwill-change
при использовании с одним из вышеуказанных значений1: Я постараюсь поддерживать этот список в актуальном состоянии..
PS
Перевод наиболее значимых комментариев:
@MiXT4PE это определено в спецификации, так что так и должно быть. Вы, вероятно, можете спросить, почему они определяют это именно так ... Я почти уверен, что за этим выбором стоит причина (вероятно, сложная). – @Temani Afif
@ygoe во-первых, это не bug, это задумано, как и многие функции, которые нам не нравятся, но с которыми мы должны работать (очистить плавающее пространство, схлопывать поля и т. д.), поэтому вам следует адаптировать свой код, чтобы преодолеть это. Универсального решения не существует, но в зависимости от вашего случая наверняка найдется решение. Вы можете задать вопрос, добавив свой конкретный код, чтобы посмотреть, сможем ли мы изменить вашу логику, чтобы удовлетворить ваши требования и решить проблему. – @Temani Afif
Свободный перевод ответа от участника @Temani Afif.