Tengo un encabezado adhesivo que utiliza IntersectionObserver para obtener una clase cuando está atascado, lo que luego oculta algunos elementos y reduce el tamaño del logotipo. Por supuesto, cuando la altura del encabezado se reduce, también lo hace la altura del desplazamiento, por lo que si se desplaza hacia abajo lo suficiente como para reducir el encabezado, se reduce y luego se da cuenta de que ya no está atascado, por lo que crece, pero eso hace que se reduzca de nuevo. por lo que crece, y así sucesivamente en un ciclo infinito. Esto parece ser más atroz en Chrome, pero también lo he visto suceder en Firefox (aunque Firefox parece reconocer lo que está sucediendo y solucionarlo).
Probé varias cosas, incluido un setTimeout() para retrasar cuando se elimina la clase, agregando un margin-bottom equivalente al encabezado cuando se reduce, mostrando un elemento oculto con una height del espacio reducido, pero nada parece arreglar esto problema.
Sé que también he visto esto en otros sitios antes, y sospecho que esto es solo un problema sistémico con la reducción de encabezados, pero ¿hay algo que pueda hacer para evitar que esto suceda? Estoy fuera de las ideas.
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 y el marcado son un poco más complicados (y ligeramente irrelevantes), así que si es necesario, consulte nuestro sitio de demostración aquí. https://gepl.myweblinx.net/
Si se necesita algo más, con gusto lo agregaré.
EDICIÓN 1: Veo que esta respuesta sugiere colocar un contenedor alrededor del elemento que retiene la altura correcta, pero que no funcionará con la position: sticky; como position: sticky; solo funciona para el contenedor más cercano (a menos que alguien sepa cómo evitar esto)
EDICIÓN 2: estaba pensando demasiado en la respuesta de mi primera edición
Bueno, esa fue una solución sorprendentemente obvia... Gracias a esta respuesta , pude darme cuenta de que si establezco una altura fija en el elemento adhesivo, pero dejo que el contenido de ese elemento se reduzca, el problema desaparece.
Esencialmente:
<div class="sticky-block" style="height:140px;"> <div class="header-block"> ... </div> <div class="navigation-block"> ... </div> </div>En mi caso, estas soluciones no funcionaron, Chrome en Android todavía tenía el problema de parpadeo. Mi solución fue fijar la posición de mi encabezado y tener un div ficticio detrás que cambia de tamaño para tener la misma altura que el encabezado.
<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>