收缩 sticky sticky header 导致 Blink/Webkit 在某些滚动位置闪烁
Shrinking sticky sticky header causes flicker in Blink/Webkit at certain scroll positions
我有一个粘性 header,它在卡住时利用 IntersectionObserver
获得 class,然后隐藏一些元素并减小徽标的大小。当然,当 header 的高度缩小时,滚动高度也会缩小,因此如果向下滚动 刚好 缩小 header,它就会缩小,然后意识到它不再卡住所以增长,而是导致它再次收缩,所以它增长,等等无限循环。这在 Chrome 中似乎是最令人震惊的,但我已经看到它也发生在 Firefox 中(尽管 Firefox 似乎认识到正在发生的事情并自行解决)。
我已经尝试了很多东西,包括 setTimeout()
在 class 被删除时延迟,在 header 收缩时添加等价的 margin-bottom
,显示height
缩小 space 的隐藏元素,但似乎无法解决此问题。
我知道我之前也在其他网站上看到过这种情况,我怀疑这只是缩小 headers 的系统性问题,但我能做些什么来防止这种情况发生吗?我没主意了。
const OBSERVER = new IntersectionObserver(
([e]) => e.target.classList.toggle("js-is-sticky", e.intersectionRatio < 1),
{
rootMargin: document.getElementById("wpadminbar") ? "-32px 0px 0px 0px" : "0px 0px 0px 0px",
threshold: [1],
}
);
OBSERVER.observe(document.querySelector(".sticky-block"));
CSS 和标记有点复杂(并且稍微不相关),所以如果需要,请参考我们的演示站点。 https://gepl.myweblinx.net/
如果需要其他任何内容,我很乐意添加。
编辑 1:我看到 this answer 建议在保持正确高度的元素周围放置一个容器,但这不适用于 position: sticky;
,因为 position: sticky;
仅适用于最近的容器(除非有人知道如何解决这个问题?)
编辑 2:我对第一次编辑的答案想得太多了
好吧,这是一个非常明显的解决方案...感谢 this answer,我能够弄清楚如果我只是在粘性元素上设置一个固定的高度,但让该元素的内容缩小,问题就解决了。
本质上:
<div class="sticky-block" style="height:140px;">
<div class="header-block">
...
</div>
<div class="navigation-block">
...
</div>
</div>
在我的情况下,这些解决方案不起作用,Android 上的 Chrome 仍然存在闪烁问题。我的解决方案是固定我的页眉位置,并在其后面放置一个虚拟 div,将其调整为与页眉相同的高度。
<html>
<head>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
<style>
:root {
--lightGrey: #bbbbbb;
}
body {
margin: 0;
width: 100%;
height: 500%;
display: grid;
grid-template-columns: repeat(3, 1fr);
grid-template-rows: repeat(9, auto);
grid-column-gap: 0px;
grid-row-gap: 0px;
}
header {
width: 100%;
grid-area: 1 / 1 / 1 / 4;
position: fixed;
top: 0;
z-index: 100;
background-color: var(--lightGrey);
}
.headerBackground {
grid-area: 1 / 1 / 1 / 4;
background-color: var(--lightGrey);
height: fit-content;
}
</style>
</head>
<body>
<header>My Header</header>
<div class="headerBackground">Background div</div>
</body>
<script>
// Changes the header once you have scrolled down by 100 pixels or more
$(window).scroll(function () {
if ($(window).scrollTop() >= 100) {
$('header').css('height', '20vw');
$('header').css({ 'font-size': '4vw', 'padding': '5vw' });
} else if ($(window).scrollTop() == 0) {
$('header').attr('style', '');
}
});
// This keeps the space behind the header at the same height as the header to get around the flickering sticky
$(".headerBackground").css({ 'height': ($("header").height() + 'px') });
</script>
</html>
我有一个粘性 header,它在卡住时利用 IntersectionObserver
获得 class,然后隐藏一些元素并减小徽标的大小。当然,当 header 的高度缩小时,滚动高度也会缩小,因此如果向下滚动 刚好 缩小 header,它就会缩小,然后意识到它不再卡住所以增长,而是导致它再次收缩,所以它增长,等等无限循环。这在 Chrome 中似乎是最令人震惊的,但我已经看到它也发生在 Firefox 中(尽管 Firefox 似乎认识到正在发生的事情并自行解决)。
我已经尝试了很多东西,包括 setTimeout()
在 class 被删除时延迟,在 header 收缩时添加等价的 margin-bottom
,显示height
缩小 space 的隐藏元素,但似乎无法解决此问题。
我知道我之前也在其他网站上看到过这种情况,我怀疑这只是缩小 headers 的系统性问题,但我能做些什么来防止这种情况发生吗?我没主意了。
const OBSERVER = new IntersectionObserver(
([e]) => e.target.classList.toggle("js-is-sticky", e.intersectionRatio < 1),
{
rootMargin: document.getElementById("wpadminbar") ? "-32px 0px 0px 0px" : "0px 0px 0px 0px",
threshold: [1],
}
);
OBSERVER.observe(document.querySelector(".sticky-block"));
CSS 和标记有点复杂(并且稍微不相关),所以如果需要,请参考我们的演示站点。 https://gepl.myweblinx.net/
如果需要其他任何内容,我很乐意添加。
编辑 1:我看到 this answer 建议在保持正确高度的元素周围放置一个容器,但这不适用于 position: sticky;
,因为 position: sticky;
仅适用于最近的容器(除非有人知道如何解决这个问题?)
编辑 2:我对第一次编辑的答案想得太多了
好吧,这是一个非常明显的解决方案...感谢 this answer,我能够弄清楚如果我只是在粘性元素上设置一个固定的高度,但让该元素的内容缩小,问题就解决了。
本质上:
<div class="sticky-block" style="height:140px;">
<div class="header-block">
...
</div>
<div class="navigation-block">
...
</div>
</div>
在我的情况下,这些解决方案不起作用,Android 上的 Chrome 仍然存在闪烁问题。我的解决方案是固定我的页眉位置,并在其后面放置一个虚拟 div,将其调整为与页眉相同的高度。
<html>
<head>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
<style>
:root {
--lightGrey: #bbbbbb;
}
body {
margin: 0;
width: 100%;
height: 500%;
display: grid;
grid-template-columns: repeat(3, 1fr);
grid-template-rows: repeat(9, auto);
grid-column-gap: 0px;
grid-row-gap: 0px;
}
header {
width: 100%;
grid-area: 1 / 1 / 1 / 4;
position: fixed;
top: 0;
z-index: 100;
background-color: var(--lightGrey);
}
.headerBackground {
grid-area: 1 / 1 / 1 / 4;
background-color: var(--lightGrey);
height: fit-content;
}
</style>
</head>
<body>
<header>My Header</header>
<div class="headerBackground">Background div</div>
</body>
<script>
// Changes the header once you have scrolled down by 100 pixels or more
$(window).scroll(function () {
if ($(window).scrollTop() >= 100) {
$('header').css('height', '20vw');
$('header').css({ 'font-size': '4vw', 'padding': '5vw' });
} else if ($(window).scrollTop() == 0) {
$('header').attr('style', '');
}
});
// This keeps the space behind the header at the same height as the header to get around the flickering sticky
$(".headerBackground").css({ 'height': ($("header").height() + 'px') });
</script>
</html>