Cómo hacer un menú hamburguesa solo con HTML y CSS
En el diseño responsive es muy frecuente realizar el conocido como menú hamburguesa, el cual recibe su nombre por el relativo parecido que tiene el típico icono con 3 barras con el famoso manjar habitual de restaurantes de comida rápida.
Aunque para lograr la típica funcionalidad de estos menús se suele recurrir al uso de JavaScript, con un poco de ingenio es posible implementar uno de estos menús solo con HTML5 y CSS3.
Antes de empezar es importante remarcar que, para este ejemplo, voy a usar la hoja de estilos reset.css como base, y los iconos de Font Awesome para los dibujos que vamos a necesitar (las 3 barrás para desplegar el menú, y el aspa para cerrar el menú). Si bien el reset.css es opcional, los iconos de Font Awesome son fundamentales para este ejemplo. Aunque el ejemplo, con los cambios adecuados, debería de funcionar perfectamente si usas otros iconos, imágenes o elementos SVG.
El truco para realizar la funcionalidad de este tipo de menú hamburguesa, reside en dos aspectos clave:
- Usar un input de tipo checkbox para saber cuando el menú está visible o no.
- Usar el selector de hermanos generales para lograr que el estado del checkbox se refleje en el menú.
La segunda condición tiene una importante implicación, y es que resulta imprescindible que el checkbox y el menú sean hermanos en la jerarquia del HTML y, además, el checbox aparezca antes en el HTML.
Por lo que para cumplir estas condiciones el HTML que vamos a usar deberia de ser similar al siguiente:
<div class="respmenu"> <input type="checkbox"> <i class="fas fa-bars"></i> <i class="fas fa-times"></i> <nav> <ul> <li><a href="#">Item 1</a></li> <li><a href="#">Item 2</a></li> <li><a href="#">Item 3</a></li> <li><a href="#">Item 4</a></li> <li><a href="#">Item 5</a></li> </ul> </nav> </div>
Tal y como se puede observar, el input de tipo checkbox y el nav con la lista de enlaces del menú, son hermanos. Esto, como ya se ha comentado, es fundamental para después lograr reflejar el estado del checkbox en la visibilidad del menú.
Antes de entrar en detalle en el CSS que va a realizar la magia, vamos a aplicar un poquito de código CSS para simplemente dar algo de aspecto al menú:
body { font-family: sans-serif; } .respmenu a { color: inherit; text-decoration: none; display: block; padding: 10px 20px; border-bottom: 2px solid #456789; max-width: 200px; background: #234567; font-variant: small-caps; text-shadow: 1px 1px black; }
Y ahora vamos a ver el resto del código CSS. En este código vemos que aparece en varios sitios el valor 48px. Este valor viene a ser el tamaño del icono de la hamburguesa. Si lo cambiamos para hacerlo más grande o pequeño, debemos de cambiarlo en todos los sitios donde aparece dicho valor.
.respmenu input[type="checkbox"], .respmenu .fa-bars, .respmenu .fa-times { position: absolute; box-sizing: border-box; margin: 0; padding: 0; right: 0; top: 0; width: 48px; height: 48px; } .respmenu .fa-bars, .respmenu .fa-times { font-size: 48px; pointer-events: none; } .respmenu input[type="checkbox"] { opacity: 0; } .respmenu { color: white; position: relative; background: #123456; min-height: 48px; } .respmenu nav { display: none; } .respmenu input:checked ~ nav { display: block; } .respmenu input:checked ~ .fa-bars { display: none; } .respmenu input:not(:checked) ~ .fa-times { display: none; }
Gracias al selector de de hermanos generales (~) podemos hacer que cuando el input esta en estado :checked, se muestre el nav, y cuando no se encuentra en dicho estado, el menú se oculte. Algo similar hacemos con los iconos de Font Awesome para mostrar/esconder el icono adecuado según el estado del checkbox.
La otra parte de la magia sucede gracias a position: absolute;, que nos permite colocar los iconos justo encima del checkbox. Finalmente, con pointer-events: none; hacemos que los iconos sean «transparentes» a los eventos del ratón, de modo que pese a estar encima del checkbox, no van a recibir ningún click del ratón, y por lo tanto será el checkbox el que los reciba a pesar de estar debajo de los iconos.
Y nada más. Espero que este truco sobre el diseño del menú hamburguesa os haya resultado interesante. Si es así, seguramente también os interese saber como hacer un slider solo con HTML y CSS. Por supuesto, también podéis echarle un vistazo al resto de nuestros artículos de desarrollo Web. Nos vemos en un próximo artículo.
Divar
como hago para que el menu se oculte cuando doy click en cualquier parte del documento (body) gracias de antemano Abel
Abel Camarena
Hola Divar, lo que pides no es posible sin usar javascript, y si vas a usar javascript existen mejores formas de hacer el menú que la explicada en el artículo. La gracia de la forma explicada en el artículo justamente está en no usar javascript.
Miguel
Hola Abel. Muy bueno. ¿Cómo hago para que se muestre el hamburguer en celus, pero un menú normal en PC?
Abel Camarena
Puedes usar esta regla de CSS para colocar el codigo que solo se aplicará a dispositivos móviles
@media (pointer: coarse) {
/* aqui pones el código CSS que solo se ejecutará si el dispositivo es movil */
}
Del mismo modo, puedes usar esta otra para escritorio
@media (pointer: fine), (pointer: none) {
/* aqui el codigo CSS que se ejecutará solo en escritorio */
}
Tienes más detalles aqui:
https://developer.mozilla.org/en-US/docs/Web/CSS/@media/pointer
Javi
Ya funcionó, todo perfecto. Mil gracias y perdón por el comentario de que no funcionaba.
Javi
Por desgracia no me funcionó. Lo que es el estilo del menú, sí, pero me aparecen todos los iconos y todo el menú, incluso el checkbox. Pero ya está.
yuli
ami si me queda bien pero me aparece unos puntos y no esta flexible .le subo de xoom y y se daña
Abel Camarena
Hola Yuli
Los puntos te salen porque no estas usando el reset.css tal y como se indica en el artículo.
Respecto al zoom del navegador, es raro, debería de funcionarte sin problemas. Como se te daña exactamente?
Saludos,
Eduardo
Gracias
Tardeus98
hola como hago para que aparezca los iconos
Abel Camarena
Hola Tardeus,
Tal y como explica el artículo, simplemente tienes que añadir el font awesome.
La forma más sencilla es añadir lo siguiente al head de tu documento HTML:
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.2.0/css/all.min.css">
Saludos,
Alexia
Como puedo separarlo de la derecha? me queda pegado
Abel Camarena
Puedes aumenta el valor de la propiedad CSS «right». Por ejemplo:
.respmenu input[type="checkbox"], .respmenu .fa-bars, .respmenu .fa-times {
position: absolute;
box-sizing: border-box;
margin: 0;
padding: 0;
right: 20px;
top: 0;
width: 48px;
height: 48px;
}
Diaz
como puedo colocar la hamburguesa a la izquierda? 🙁
Abel Camarena
Hola Diaz,
Prueba a añadir el siguiente código CSS al final del código del artículo:
.respmenu input[type="checkbox"], .respmenu .fa-bars, .respmenu .fa-times {
right: initial;
left: 0;
}
.respmenu {
padding-top: 48px;
min-height: initial;
}
Saludos,
Andrés H.
No me funciona
Abel Camarena
Hola Andrés, que es lo que te falla?
El código funciona correctamente. ¿Estas usando «Font Awesome» tal y como se indica en el artículo?
En caso negativo, prueba a usar el siguiente CDN:
https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0/css/all.min.css
Jose
Cómo puedo hacer para que el menu al momento de volverlo responsivo se puede desplazar sobre los demás elementos
Abel Camarena
No termino de entender tu pregunta Jose, ¿a que te refieres exactamente con «se pueda desplazar sobre los demás elementos»?
Camila
te refieres a la propiedad «posititon: sticky» quizas?
Christian García.
Muy bueno el ejemplo, pero no logro hacer que el icono en vez de quedar encima de la lista quede separado, es decir el icono bien arriba y debajo si la lista.
Abel Camarena
Hola Christian, si he entendido bien la pregunta, lo único que tienes que hacer es colocar relleno (padding) superior dentro del div.respmenu; o bien colocar algún (o algunos) elementos como por ejemplo un párrafo antes del input checkbox. De este modo la lista bajará, y como el icono esta puesto con position, se quedará donde está.
Christian García.
Esta muy bueno el ejemplo, pero cuando lo implemento, el icono queda encima de la lista y yo quiero que queden separados, es decir que salga el icono en la parte de arriba y debajo la lista.
Arturo Solano
Gracias, muy bien explicado
Abel Camarena
De nada. Échale un vistazo al resto de nuestros artículos, tal vez encuentres otras cosas que te puedan interesar 😉
Yederith
¡Muchas gracias! Me resultó muy útil. (No sé por qué tenías calificación de -11, ya te pasé un +).
¡Saludos!
Abel Camarena
Gracias a ti Yederith por el comentario y por el +