Header fijo: CSS position: sticky y ocultar al desplazar
Guía de header fijo
Header fijo en CSS: position sticky, encoger y ocultar al desplazar | We.Inc
Crea un header fijo con position: sticky y luego añade encogimiento y ocultación al desplazar. Demo en vivo, desplazamiento de anclas con scroll-margin, arreglos de z-index y un pequeño hook de React.
Dale al header position: sticky y top: 0, además de un fondo y un z-index, y se quedará fijo mientras la página se desplaza. Solo se queda pegado dentro de su elemento padre, y un ancestro con overflow definido puede impedirlo. Para un header que se oculta al desplazar, alterna una clase con translateY desde un listener de scroll.
sticky frente a fixed para headers
position: sticky
position: fixed
Ocupa espacio en la maquetación
Sí
No, añade padding al body
Fijo respecto a
El ancestro con scroll más cercano
El viewport
Necesita un inset como top: 0
Sí, o se comporta como relative
Normalmente
Crea un contexto de apilamiento
Sí
Sí
Se detiene al final de su padre
Sí
No
Los headers fijos son una línea de CSS hasta que dejan de serlo: el header se niega a quedarse pegado, los enlaces de ancla caen debajo de él o un menú desplegable se cuela detrás del contenido. Esta página cubre esa línea de CSS y luego cada uno de esos fallos, con una demo de scroll en vivo en la que puedes cambiar entre los modos simple, encoger y ocultar.
Desplázate dentro de la caja de la demo. El header se queda pegado a esa caja, igual que un header real se queda pegado a la página.
Cambia el modo a encoger u ocultar al desplazar y vuelve a desplazarte en ambas direcciones.
Haz clic en un enlace de sección de la demo para ver cómo scroll-margin-top mantiene el título libre del header.
Copia el CSS y el hook que correspondan al modo que quieres.
Si sticky no hace nada, busca un ancestro con overflow: hidden, auto o scroll. El header se queda pegado a esa caja en lugar de a la página.
Un elemento sticky no puede salir de su padre. Pon el header directamente en body o en un contenedor tan alto como la página.
Dale al header un fondo sólido o ligeramente translúcido, o el contenido se verá a través de él al desplazarte.
Define scroll-padding-top en html con la altura del header para que cada enlace de ancla y cada elemento enfocado se detenga debajo de él.
Respeta la reducción de movimiento: omite la animación de deslizamiento para quienes pidieron menos movimiento.
Preguntas frecuentes
¿Por qué no funciona mi position: sticky?
Tres causas habituales: no hay un valor de inset como top: 0, un padre que termina justo después del header y no deja espacio para quedarse pegado, o un ancestro con un overflow distinto de visible, que se convierte en la caja a la que se pega el header. Revísalas en ese orden.
¿Un header debe ser sticky o fixed?
Sticky es más sencillo porque conserva su lugar en la maquetación, así que nada salta debajo de él en la parte superior de la página. Fixed es útil cuando el header debe ir sobre un hero a pantalla completa, pero entonces tienes que añadir tú el padding a la página.
¿Cómo evito que los enlaces de ancla queden ocultos bajo un header fijo?
Añade scroll-padding-top al contenedor con scroll, normalmente html, igual a la altura del header. Para destinos puntuales puedes poner en su lugar scroll-margin-top en el propio título.
¿Por qué mi menú desplegable aparece detrás del contenido de la página?
El posicionamiento sticky crea un contexto de apilamiento, así que todo lo que hay dentro del header solo puede apilarse dentro de él. Eleva el propio header con un z-index superior al contenido posterior, por ejemplo z-index: 50, en lugar de elevar el desplegable.
Cómo funciona sticky de verdad
Un elemento sticky empieza en el flujo normal. En cuanto el scroll lo llevaría más allá de su inset, top: 0 en el caso de un header, mantiene esa posición hasta que llega el final de su padre y lo empuja fuera.
La caja a la que se pega es el ancestro más cercano con un mecanismo de scroll, lo que incluye overflow: hidden. Por eso un contenedor añadido para recortar un carrusel puede romper sin avisar un header que está muy lejos de él.
Ocultar al bajar, mostrar al subir
Compara la posición de scroll actual con la anterior. Bajar más allá de un pequeño umbral oculta el header con transform: translateY(-100%); cualquier movimiento hacia arriba lo devuelve.
Anima transform en lugar de top o height, ya que un transform no provoca recálculo de la maquetación. Escucha el scroll con la opción passive para que el navegador nunca espere a tu manejador.
Encoger sin saltos en la maquetación
Cambiar la altura del header mientras está fijo mueve el contenido que hay debajo. Mantén fija la altura exterior y encoge el logo con transform: scale, o reduce el padding dentro de un header que ya está apartado.
Un atributo data como data-scrolled en el header mantiene las reglas de estilo en el CSS y el script en una sola línea.
El header fijo básico
Header fijo dentro de una página con scroll
Desplázate en el marco. El header se queda arriba y el enlace de ancla se detiene debajo gracias a scroll-padding-top.
Ocultar al bajar, mostrar al subir
CSS para los estados oculto y encogido
El script solo define atributos data. Todos los cambios visuales viven en el CSS.
Hook de React: useHideOnScroll
Devuelve dos booleanos que puedes pasar al header como atributos data. El umbral de 8px ignora los pequeños temblores.
Errores comunes con headers fijos
Síntomas y soluciones
Síntoma
Causa
Solución
El header se va con el scroll
Sin valor top
Añade top: 0
El header se va con el scroll
Un ancestro tiene overflow: hidden
Mueve el overflow a un contenedor más pequeño o usa overflow: clip
Se pega y luego se va antes de tiempo
El padre es corto
Coloca el header en body o en un contenedor de altura completa
Títulos de ancla ocultos
Sin desplazamiento de scroll
scroll-padding-top en html
El menú queda detrás del contenido
Contexto de apilamiento del header demasiado bajo
z-index en el propio header
El contenido se ve a través
Fondo transparente
Dale al header un color de fondo
Sticky simple
Encoger
Ocultar al desplazar
Introducción
Funciones
Precios
Contacto
Demo de scroll en vivo
Cambia entre simple, encoger y ocultar al desplazar, y luego desplázate dentro de la caja.