Introducción
Este tutorial explica con todo lujo de detalles cómo hacer que el menú de un tema WordPress se convierta en un botón hamburguesa antes de romper —es decir, detectar cuándo los elementos del menú empiezan a ocupar más ancho del disponible y cambiar a la versión colapsada automáticamente—. Se ofrecen dos estrategias: una solución CSS (media queries) y una solución robusta con JavaScript que mide el ancho real del menú y activa el botón hamburguesa dinámicamente. Incluye HTML/PHP para insertar el botón, CSS para el diseño y JS para la detección, además de consideraciones de accesibilidad y mejoras opcionales.
Estrategias generales
- CSS-only: usar media queries a un ancho fijo. Es simple pero necesita ajustar el punto de quiebre manualmente según el contenido y el diseño.
- JavaScript dinámico: medir el ancho real del contenedor y el ancho total de los ítems del menú si los ítems superan el contenedor, añadir una clase que activa la versión hamburguesa. Es más fiable para menús con textos variables, iconos o cuando los usuarios cambian el tamaño de la fuente.
Requisitos previos
- Tema hijo o acceso para editar header.php o los archivos correspondientes del tema.
- Conocimiento básico de CSS y JavaScript en WordPress.
- Capacidad para insertar wp_nav_menu y un botón toggle (hamburguesa).
1) Marcar el HTML/PHP del menú en tu tema
Añade un botón toggle para la versión hamburguesa y el contenedor de navegación. El ejemplo siguiente muestra la estructura típica para header.php o la plantilla correspondiente. El botón incluye atributos ARIA para accesibilidad.
lt!-- header.php (o plantilla parcial del menú) --gt
ltbutton class=menu-toggle id=menu-toggle aria-expanded=false aria-controls=site-navigationgt
ltspan class=sr-onlygtAbrir menúlt/spangt
ltspan class=hamburgergt
ltspan class=bargtlt/spangt
ltspan class=bargtlt/spangt
ltspan class=bargtlt/spangt
lt/spangt
lt/buttongt
ltnav id=site-navigation class=main-navigation role=navigationgt
lt?php
wp_nav_menu( array(
theme_location =gt primary,
menu_class =gt primary-menu,
container =gt false
) )
?gt
lt/navgt
Notas
- La clase menu-toggle es el botón visible que abrirá/cerrará la navegación en dispositivos pequeños o cuando el menú esté “colapsado”.
- La estructura que genera wp_nav_menu suele ser ltul class=primary-menugtltligt…lt/ligtlt/ulgt, lo que facilita medir los ltligt con JavaScript.
2) CSS básico: estilos del botón hamburguesa y comportamiento
A continuación un CSS base para crear la hamburguesa, ocultar/mostrar el menú y animar la apertura. Este CSS asume que la clase menu-collapsed en el ltbodygt o en el contenedor indica que se debe mostrar el toggle en lugar del menú horizontal.
/ Estilos base: menú horizontal en desktop /
.main-navigation { display: block }
.primary-menu { display: flex gap: 1rem list-style: none margin: 0 padding: 0 }
.primary-menu gt li { white-space: nowrap }
/ Botón hamburguesa - por defecto oculto en desktop /
.menu-toggle { display: none align-items: center gap: .5rem background: none border: 0 cursor: pointer padding: .5rem }
.menu-toggle .hamburger { display: inline-block width: 24px height: 18px position: relative }
.menu-toggle .bar { display: block height: 2px background: #111 margin: 4px 0 transition: transform .25s ease, opacity .2s ease }
/ Estado abierto (al añadir .menu-open al cuerpo o nav) /
body.menu-open .primary-menu { display: block position: absolute top: 60px right: 10px background: #fff box-shadow: 0 6px 18px rgba(0,0,0,.12) padding: 1rem border-radius: 6px }
body.menu-open .menu-toggle[aria-expanded=true] .bar:nth-child(1) { transform: translateY(6px) rotate(45deg) }
body.menu-open .menu-toggle[aria-expanded=true] .bar:nth-child(2) { opacity: 0 }
body.menu-open .menu-toggle[aria-expanded=true] .bar:nth-child(3) { transform: translateY(-6px) rotate(-45deg) }
/ Cuando el menú esté colapsado (convertido a hamburguesa) mostramos el botón y ocultamos la lista horizontal /
body.menu-collapsed .menu-toggle { display: inline-flex }
body.menu-collapsed .primary-menu { display: none }
/ Mobile por defecto: opcionalmente forzamos comportamiento /
@media (max-width: 768px) {
.menu-toggle { display: inline-flex }
.primary-menu { display: none }
}
Explicación breve
- La clase body.menu-collapsed indica que el menú debe presentarse como hamburguesa. Puedes aplicar esa clase al body, al nav o a un contenedor específico en el JS del siguiente paso veremos cómo hacerlo.
- Los estilos de .menu-open muestran el menú desplegado cuando el usuario pulsa la hamburguesa puedes adaptar la posición (off-canvas, dropdown, full-screen) según tus necesidades.
3) JavaScript: medir el ancho y activar el modo hamburguesa automáticamente
La parte clave para “antes de romper” es medir el ancho total de los ítems del menú y compararlo con el ancho disponible del contenedor. Si los ítems no caben, añadimos la clase menu-collapsed para mostrar la hamburguesa. Además, añadiremos la lógica para abrir/cerrar el menú, manejar Escape, clic fuera y resize con debounce.
// Archivo: menu-collapse.js
(function(){
const NAV_SELECTOR = #site-navigation
const MENU_SELECTOR = .primary-menu
const TOGGLE_ID = menu-toggle
const COLLAPSE_CLASS = menu-collapsed
const OPEN_CLASS = menu-open
const DEBOUNCE_MS = 120
const nav = document.querySelector(NAV_SELECTOR)
const menu = nav ? nav.querySelector(MENU_SELECTOR) : null
const toggle = document.getElementById(TOGGLE_ID)
if (! nav ! menu ! toggle) return
// Suma los anchos de los Comentarios sobre el JS
- Se mide el ancho total de los ltligt y se compara con el ancho del nav, añadiendo un margen de seguridad para colapsar antes.
- MutationObserver detecta cambios dinámicos en el menú (por ejemplo, plugins, traducciones u items añadidos por el usuario), asegurando que la decisión se reevalúe.
- Se usa un debounce para no ejecutar la medición continuamente durante el resize.
- La clase body.menu-collapsed activa el estilo hamburguesa (CSS anterior). Puedes aplicar la clase al nav si prefieres un alcance más limitado.
4) Mejores prácticas de accesibilidad (A11Y)
- Usa aria-expanded en el botón y aria-controls apuntando al id del nav.
- Incluye texto accesible (por ejemplo .sr-only con Abrir menú) que describa la acción para lectores de pantalla.
- Permite cerrar con Escape y devolver el foco al botón al cerrar.
- Si el menú desplegable cubre la pantalla, considera trap focus (capturar el foco dentro del panel) o, al menos, asegurar que el tab order sea lógico.
5) Variantes y mejoras opcionales
- Off-canvas completo: en vez de mostrar un dropdown, puedes desplazar el contenido y mostrar un panel lateral usando transform CSS y role=dialog con aria-modal.
- Medir anchos con resizeObserver del nav: si quieres reaccionar a cambios de tamaño del contenedor por layout, puedes usar ResizeObserver además de window.resize.
- Animaciones y rendimiento: evita animar propiedades que fuerzan reflow en grandes dispositivos usa transform y opacity para animaciones suaves.
- Evitar ruptura con textos largos: si los items del menú pueden ser muy largos, considera truncarlos con text-overflow: ellipsis de lo contrario, el JS detectará y colapsará cuando sea necesario.
6) Ejemplo de media query CSS (fallback simple)
Si prefieres no usar JavaScript, puedes usar una media query con un punto de quiebre calculado según el número típico de items y longitud de texto. Es menos flexible pero sirve en muchos casos.
/ Ejemplo simple: colapsar antes de 900px /
@media (max-width: 900px) {
body .primary-menu { display: none }
body .menu-toggle { display: inline-flex }
}
7) Manejo de submenús
Si tu menú tiene submenús desplegables, añade control para expandir submenús en versión colapsada: íconos botones para cada item que tenga children. Puedes usar CSS para ocultarlos y JS para alternar la clase is-open en cada li padre.
// Toggle simple de submenú para versión colapsada
document.addEventListener(click, function(e){
const btn = e.target.closest(.submenu-toggle)
if (!btn) return
const li = btn.closest(li)
li.classList.toggle(is-open)
})
8) Checklist final antes de publicar
- Probar en distintos anchos y dispositivos (desktop, tablet, móvil).
- Comprobar con tamaños de fuente distintos (ajustar zoom y configuraciones de accesibilidad).
- Verificar teclado: Tab, Shift Tab, Enter, Space y Escape para abrir/cerrar y navegar.
- Comprobar que la experiencia sea correcta cuando se cambian los menús desde el personalizador de WordPress o plugins que inyectan ítems.
- Medir rendimiento: el MutationObserver y ResizeObserver son ligeros si se usan correctamente evita cálculos caros en bucles frecuentes.
Conclusión
La solución ideal para transformar el menú en un botón hamburguesa antes de que el contenido rompa combina estilos CSS accesibles con una detección JavaScript que mida el ancho real de los elementos del menú. Esto evita puntos de quiebre rígidos y ofrece una mejor experiencia en temas con menús dinámicos o textos variables. Implementa la estructura PHP/HTML, los estilos CSS y el script de medición y prueba extensamente en distintos escenarios y tamaños de fuente.
Leave a Reply