Introducción
Este tutorial explica paso a paso cómo crear un mega menú sencillo usando solo HTML y CSS, sin JavaScript. El objetivo es conseguir un menú desplegable amplio, con varias columnas y enlaces organizados, que funcione bien en escritorios y que sea accesible mediante teclado. Incluye la estructura HTML, el CSS necesario, pautas de integración en WordPress y recomendaciones de personalización.
Resumen del enfoque
La técnica se basa en una lista anidada (ul / li) para el menú principal y sub-menús amplios que se muestran mediante reglas CSS (:hover y :focus-within) y posicionamiento absoluto dentro del flujo visual. Para la versión móvil se usa una versión responsiva que convierte el menú en bloque apilado (sin JavaScript) con media queries.
Estructura HTML del mega menú
A continuación tienes una estructura limpia y semántica que puedes pegar en un bloque HTML en WordPress o en la plantilla de tu tema (header.php). El HTML está preparado para los estilos CSS posteriores.
CSS completo y explicado
Este CSS proporciona diseño, posicionamiento, transiciones suaves, soporte para teclado y un comportamiento responsivo básico. Pégalo en Apariencia → Personalizar → CSS Adicional o en style.css de tu tema hijo.
/ Reset y base /
.mega-menu-wrap { font-family: system-ui, Arial, sans-serif }
.mega-menu-wrap .menu { list-style: none margin: 0 padding: 0 display: flex gap: 1rem align-items: flex-start }
.mega-menu-wrap .menu-item { position: relative }
/ Enlaces /
.mega-menu-wrap a { text-decoration: none color: #222 display: inline-block padding: .6rem .8rem }
.mega-menu-wrap a:focus { outline: 2px solid #2563eb outline-offset: 2px }
/ Panel del mega menú (oculto por defecto) /
.mega-panel {
position: absolute
left: 0
top: 100%
display: none
background: #fff
box-shadow: 0 6px 20px rgba(0,0,0,.08)
padding: 1rem
border-radius: 6px
z-index: 1000
width: max(40rem, 70vw) / ancho flexible /
box-sizing: border-box
margin-top: .6rem
}
/ Columnas internas /
.mega-panel .mega-column { width: 33.333% float: left box-sizing: border-box padding: 0 .8rem }
.mega-panel h4 { margin: 0 0 .5rem 0 font-size: .95rem color: #111 }
.mega-panel ul { list-style: none padding: 0 margin: 0 }
.mega-panel li { margin: .35rem 0 }
/ Mostrar panel al pasar el ratón o al enfocar con teclado /
.menu-item.has-mega:hover > .mega-panel,
.menu-item.has-mega:focus-within > .mega-panel {
display: block
}
/ Flebox fallback y limpieza floats /
.mega-panel::after { content: display: table clear: both }
/ Transiciones opcionales /
.mega-panel { opacity: 0 transform: translateY(6px) transition: opacity .18s ease, transform .18s ease pointer-events: none }
.menu-item.has-mega:hover > .mega-panel,
.menu-item.has-mega:focus-within > .mega-panel {
opacity: 1 transform: translateY(0) pointer-events: auto
}
/ Responsive: menú vertical sencillo en pantallas pequeñas /
@media (max-width: 900px) {
.mega-menu-wrap .menu { flex-direction: column gap: 0 }
.mega-panel { position: static width: 100% box-shadow: none margin-top: .25rem border-radius: 0 padding: .6rem 0 display: none }
.mega-panel .mega-column { width: 100% padding: .25rem .8rem float: none }
.menu-item.has-mega:focus-within > .mega-panel,
.menu-item.has-mega:hover > .mega-panel { display: block }
}
Explicación de las reglas clave
- Contenedor flexible: La lista principal (.menu) usa display:flex para distribuir los items en horizontal y mantener el control del espaciado.
- Panel absoluto: El .mega-panel está posicionado absolute relativo al .menu-item, lo que permite que el panel se superponga al contenido y tenga ancho independiente.
- Mostrar/ocultar sin JavaScript: Se usa :hover y :focus-within para mostrar el panel. :focus-within permite que el menú sea desplegable cuando un enlace interno recibe foco desde teclado.
- Transiciones: Opacidad y transform para animación suave al aparecer. pointer-events se usa para evitar interacciones cuando está oculto.
- Responsivo: Media query que convierte el menú en bloque apilado y coloca los paneles como secciones dentro del flujo normal.
Accesibilidad
- Usa elementos a reales para todos los enlaces para que sean fácilmente navegables y detectables por lectores de pantalla.
- El foco visual está gestionado con :focus asegúrate de que el color y el contraste cumplan WCAG.
- En ausencia de JavaScript, :focus-within permite que usuarios de teclado abran y naveguen el panel. Si necesitas comportamiento más complejo (cerrar/abrir con ESC, manejo de flechas), entonces sería necesario añadir JavaScript y roles ARIA.
Integración en WordPress
- Opción rápida (bloque): Ve a Apariencia → Widgets o al editor de páginas, añade un bloque HTML personalizado y pega la estructura HTML del menú. Luego pega el CSS en Apariencia → Personalizar → CSS Adicional.
- Opción tema hijo: Si deseas integrarlo en la cabecera de forma permanente, crea un tema hijo y edita header.php para incluir la estructura. Añade el CSS en style.css del tema hijo o en un archivo .css que enqueues mediante functions.php.
- Menús dinámicos (opcional): Para integrar con el sistema de Menús de WordPress y generar la lista automáticamente, necesitarás usar wp_nav_menu y adaptar el walker para emitir las clases (.has-mega y .mega-panel). Esto ya requiere PHP, pero la versión simple del tutorial usa HTML estático.
Tabla rápida: dónde pegar cada cosa
| Código | Dónde pegar |
| HTML del menú | Bloque HTML personalizado o header.php del tema hijo |
| CSS del menú | Apariencia → Personalizar → CSS Adicional o style.css del tema hijo |
Variantes y personalizaciones
- Añadir iconos: utiliza iconos SVG inline en los enlaces dentro del HTML del panel para mayor claridad visual.
- Imágenes o promos: dentro de una columna puedes incluir una tarjeta promocional con imagen y CTA si lo haces, controla el tamaño y el responsive con reglas CSS.
- Columnas variables: cambia el ancho de .mega-column o usa display:grid en .mega-panel para un control más fino de filas y columnas.
- Soporte para submenús profundos: anida más listas y adapta :hover / :focus-within para cada nivel.
Consejos finales y resolución de problemas
- Si el panel se corta por overflow del contenedor padre, asegúrate de que los contenedores superiores no tengan overflow:hidden, o coloca el .mega-panel más arriba en el DOM y usa posicionamiento con transform/offset si es necesario.
- Comprueba el z-index cuando tengas menús superpuestos para evitar que otros elementos tapen el mega-panel.
- Prueba con teclado: tabula por el menú y verifica que el panel permanezca abierto mientras el foco esté dentro.
- Si necesitas compatibilidad muy antigua, evita :focus-within y añade una versión con clases toggled por JavaScript. Para la mayoría de navegadores modernos :focus-within funciona bien.
Leave a Reply