Introducción
Este tutorial explica, paso a paso y con todo lujo de detalles, cómo implementar en WordPress un menú sticky que se reduce al hacer scroll utilizando únicamente CSS. Presento dos métodos: uno moderno (basado en las nuevas capacidades de animación ligada al scroll) y otro compatible (técnica de cabecera duplicada) que funciona en la práctica en la mayoría de navegadores sin JavaScript. Incluyo el HTML de ejemplo para integrar en header.php o en un bloque, el CSS listo para copiar y un ejemplo de cómo encolar la hoja de estilos en un tema hijo de WordPress.
Requisitos y consideraciones previas
- Acceso al tema (preferiblemente un child theme) para editar header.php o crear un bloque de plantilla.
- Conocimientos básicos de CSS y de cómo encolar estilos en WordPress.
- Decidir si quieres dar soporte a navegadores antiguos: el método moderno ofrece una animación suave pero tiene soporte limitado la técnica duplicada es más robusta.
- Ten en cuenta la accesibilidad: asegúrate de que el menú siga siendo usable por teclado y que los botones tengan roles/aria cuando sea necesario.
Estructura HTML de ejemplo (para header.php o un bloque)
Este markup es intencionalmente sencillo. Puedes colocarlo en header.php o en un bloque HTML dentro del editor de bloques si prefieres no tocar archivos de tema.
Método A — Moderno: animación ligada al scroll (solo CSS)
Descripción: utiliza las Scroll-Linked Animations (animaciones ligadas al scroll) para interpolar la altura del header, el tamaño del logo y otras propiedades a medida que el usuario hace scroll. Ventaja: animación suave y control fino sin JavaScript. Inconveniente: soporte limitado a navegadores modernos (principalmente Chromium con la característica habilitada).
CSS (ejemplo mínimo)
/ Variables base /
:root{
--header-large: 120px
--header-small: 64px
--brand-large: 1.5rem
--brand-small: 1rem
--bg: #ffffff
}
/ Cabecera sticky básica /
.site-header {
position: sticky
top: 0
height: var(--header-large)
display: flex
align-items: center
padding: 0 1rem
background: var(--bg)
z-index: 20
box-shadow: 0 1px 0 rgba(0,0,0,0.05)
overflow: hidden
}
/ Branding /
.site-header .brand {
font-size: var(--brand-large)
transition: font-size 160ms linear
}
/ Scroll-timeline (sintaxis moderna soporte experimental en algunos navegadores) /
@keyframes shrink-header {
from { height: var(--header-large) }
to { height: var(--header-small) }
}
@keyframes shrink-brand {
from { font-size: var(--brand-large) }
to { font-size: var(--brand-small) }
}
/ Registrar y usar timeline /
@scroll-timeline headerTimeline {
source: auto / toma el scrolling de la vista /
orientation: block
scroll-offsets: 0% 200px / rango de scroll donde se anima (ajustable) /
}
/ Aplicar animaciones usando el timeline /
.site-header {
animation: shrink-header 1s linear both
animation-timeline: headerTimeline
}
.site-header .brand {
animation: shrink-brand 1s linear both
animation-timeline: headerTimeline
}
Notas importantes sobre este método:
- Ajusta scroll-offsets para definir la distancia de scroll en la que ocurre la reducción.
- En algunos navegadores puede requerirse activar características experimentales o esperar soporte más amplio.
- Si necesitas compatibilidad total, usa el Método B (duplicado).
Método B — Compatibilidad amplia: cabecera duplicada y sticky
Descripción: se colocan dos versiones de la cabecera: una grande (visible inicialmente) y una pequeña (sticky, visible cuando la grande se desplaza). Ambas con position: sticky la grande se overlayea a la pequeña mientras está en la parte superior al desplazarse la grande hacia arriba la pequeña queda visible. Es CSS-only y compatible en la práctica con la mayoría de navegadores.
HTML (ejemplo)
CSS (ejemplo robusto)
/ Variables /
:root{
--height-large: 140px
--height-small: 64px
--bg: #ffffff
}
/ Ambos elementos sticky, top:0 /
.site-condensed,
.site-header {
position: sticky
top: 0
left: 0
right: 0
}
/ Cabecera pequeña que quedará fija cuando la grande desaparezca /
.site-condensed {
height: var(--height-small)
display: flex
align-items: center
padding: 0 1rem
background: var(--bg)
z-index: 5 / por debajo de la cabecera grande mientras ésta esté visible /
box-shadow: 0 1px 0 rgba(0,0,0,0.06)
}
/ Cabecera grande, visible inicialmente /
.site-header {
height: var(--height-large)
display: flex
align-items: center
padding: 1rem
background: linear-gradient(to bottom, rgba(255,255,255,0.98), rgba(255,255,255,0.95))
z-index: 10 / queda por encima mientras esté en vista /
box-shadow: 0 2px 8px rgba(0,0,0,0.04)
}
/ Contenido y responsividad básicos /
.brand { text-decoration: none color: #111 font-weight: 700 }
.main-nav { margin-left: auto }
/ Ajustes móviles: puedes ocultar items y mostrar un toggle /
@media (max-width: 800px){
.main-nav { display: none } / sustituir por menú hamburguesa si hace falta /
}
Cómo funciona en la práctica:
- Al cargar, la cabecera grande (.site-header) está en la parte superior y superpone a .site-condensed por el z-index.
- Al hacer scroll, la cabecera grande se desplaza hacia arriba fuera de la vista —la cabecera pequeña (.site-condensed) permanece sticky en top:0 y queda visible— dando la sensación de reducción.
- Es compatible y evita JavaScript, pero la transición entre grande y pequeña es un “cambio” (no siempre una animación fluida). Para animaciones suaves con compatibilidad hay que valorar trade-offs o añadir un poco de JS.
Encolar el CSS en WordPress (ejemplo functions.php)
Guarda tu CSS en un archivo como css/shrink-header.css dentro del tema hijo y encola con:
function theme_enqueue_shrink_header() {
wp_enqueue_style( shrink-header, get_stylesheet_directory_uri() . /css/shrink-header.css, array(), 1.0 )
}
add_action( wp_enqueue_scripts, theme_enqueue_shrink_header )
Accesibilidad y SEO
- Conserva roles y atributos ARIA en el nav (role=navigation o aria-label).
- Asegúrate de que el menú sea navegable con teclado: controles visibles y foco claro.
- Evita ocultar links importantes en la cabecera condensada replica solo los elementos necesarios para navegación rápida.
- Si usas duplicado, no dupliques contenido crítico para SEO: los enlaces pueden ser los mismos, pero evita marcarlos como duplicados en microdata si te preocupa el rastreo. En la práctica esto no suele penalizar.
Personalización y buenas prácticas
- Usa variables CSS (–header-large, –header-small) para ajustar alturas fácilmente.
- Mantén la cabecera compacta en móviles y prioriza elementos (logo, botón de menú, CTA opcional).
- Controla la performance: evita sombras y filtros pesados preferible usar transform y opacity para animaciones si usas JS/animaciones.
- Prueba en distintos navegadores y dispositivos: Chrome, Firefox, Safari, Edge y navegadores móviles.
Soporte de navegadores
| Característica | Compatibilidad |
|---|---|
| position: sticky | Amplio soporte moderno (Chrome, Firefox, Edge, Safari) |
| Scroll-linked animations (@scroll-timeline) | Soporte experimental / limitado (principalmente Chromium con flags o versiones recientes) |
| Duplicated sticky approach | Funciona en la práctica en la mayoría de navegadores modernos |
Problemas comunes y soluciones rápidas
- El header no se pega (sticky no funciona): Asegúrate de que el ancestro no tenga overflow: hidden/auto position: sticky funciona dentro del contexto de scrolling del contenedor.
- La cabecera pequeña aparece debajo del contenido: Ajusta z-index y asegúrate de que top: 0 esté aplicado correctamente.
- Transición brusca al cambiar de header: Si quieres animación suave considera añadir un pequeño script para interpolar alturas o usar la opción de Scroll-Linked cuando sea posible.
- Soporte móvil: valida que el área táctil del logo y botones siga siendo adecuada en la cabecera pequeña.
Conclusión
Crear un menú sticky que se reduce al hacer scroll solo con CSS es totalmente posible la elección del método depende del compromiso entre apariencia (animaciones suaves) y compatibilidad. Para un resultado elegante y compatible sin JavaScript, la técnica de la cabecera duplicada es práctica y robusta. Si puedes aceptar limitaciones de soporte y deseas la máxima suavidad sin código, explora las animaciones ligadas al scroll en navegadores compatibles.
Leave a Reply