En este artículo vamos a explicar cómo hacer un menú horizontal o vertical responsive multinivel con HTML y CSS. Continuando con la serie de menús con HTML y CSS vamos a abordar el último y definitivo menú también llamado de tipo «hamburguesa» ☰ .
Si aún no lo has hecho, puedes ver los artículos anteriores en estos enlaces:
Para crear nuestro menú horizontal o vertical responsive multinivel vamos a utilizar la misma fuente HTML5 y los mismos estilos CSS. Pero añadiremos unas pequeñas modificaciones consiguiendo que todo se adapte al tamaño de pantalla del dispositivo, y hacerlo «Responsive».
En dispositivos con pantallas pequeñas nuestro menú inicialmente se verá «guardado» como en la siguiente imagen (tipo hamburguesa)

Al hacer clic en el icono ☰ (hamburguesa) mostraremos el primer nivel del menú como aparecería normalmente en pantallas grandes

Una vez activado el menú éste se comporta de forma natural, mostrando sus diferentes niveles de profundidad hasta salirse de pantalla (recuerda que estás en una pantalla pequeña)

El menú responsive en HTML
Lo primero que vamos a hacer es mostrar la parte de código HTML5 a modificar, justo debajo de nuestro elemento <nav> añadiremos lo siguiente:
<nav class="csMenu">
<input id="hMenuBtn" type="checkbox" />
<label for="hMenuBtn"></label>
<ul id="hMenu" class="mVerti">
<li><a href="#">Inicio</a></li>
<li><a href="#">Servicios</a></li>
<li><a href="#">Buscador</a></li>
<li><a href="#"">F.A.Q.</a></li>
<li><a href=" #">Utilidades ▼</a>
etc ...
En este artículo no veo conveniente mostrar todo el código porque ya está comentado en el artículo anterior y lo que nos interesa ahora es ver cómo se añade el efecto «hamburguesa» a un menú ya construido.
Hemos añadido dos etiquetas y modificado el primer <ul>:
<input id="hMenuBtn" type="checkbox" />
El <input> checkbox lo utilizaremos para hacer de interruptor on/off de nuestro menú utilizando sus propiedades de formulario. Le asignamos un ID único para referirnos a él de forma sencilla. El truco será detectar su porpiedad «checked» con CSS para saber si activar o desactivar propiedades de visualización<label for="hMenuBtn"></label>
El elemento <label> nos ayudará a camuflar el <input> checkbox con el icono ☰ tipo hamburguesa conocido como menú en dispositivos móviles<ul id="hMenu" class="mVerti">
Ahora debemos añadir un identificador ID a nuestro primer elemento <ul> además de la clase del tipo de menú que queremos (mHoriz, mVerti). La razón es bien sencilla, al activarse el menú «responsive» debe desaparecer todo excepto el icono ☰ y esto lo conseguimos actuando sobre la raíz <ul> mediante su ID
El funcionamiento del menú será el siguiente, en pantallas grandes los nuevos elementos <input> y <label> permanecerán «invisibles» y el menú funcionará como en el artículo menu horizontal o vertical multinivel con css, al detectar una pantalla pequeña los elementos <input> y <label> se harán visibles mientras que los elementos del menú <ul>, <li>, <a> se harán «invisibles».
Al hacer «clic» en el <input
> checkbox mostraremos el primer elemento <ul id="hMenu" ...
> del menú y a partir de aquí se comportará como siempre. Al volver a hacer clic en el <input
> checkbox volveremos a ocultar el primer elemento <ul id="hMenu" ...
>.
Explicado así es muy fácil verdad ? Noooo 🙂
Menu responsive multinivel con CSS
Aún hay muchas cosas que contar, vamos a ver los estilos CSS donde se hace la mágia de todo esto
/* Botón tipo hamburguesa en pantallas pequeñas */
#hMenuBtn {
display: none;
}
/* Menú hamburguesa */
@media (max-width: 768px) {
#hMenu {
display: none;
}
#hMenuBtn + label {
color: white;
cursor: pointer;
padding: 0 0.5em;
display: inline-block;
}
#hMenuBtn + label:hover {
background-color: green;
}
#hMenuBtn + label::before {
content: "☰";
font-size: 2rem;
line-height: 1em;
}
#hMenuBtn:checked ~ #hMenu {
display: block;
}
}
En principio estas reglas CSS no parecen gran cosa pero están llenas de peculiaridades técnicas que a mí también me cuestan entender. Vamos a verlas:
- #hMenuBtn: Este identificador lo utilizamos para «ocultar» nuestros elementos <input> y <label> y permanecerán siempre ocultos excepto si se cumple la condición de tamaño de pantalla pequeña. Entonces les aplicaremos ciertos estilos CSS.
@media (max-width: 768px)
Esto significa que en pantallas de 0 a 768 píxeles se aplicarán las siguientes reglas CSS y haremos que el menú se comporte como un icono ☰ tipo hamburguesa. Puedes modificar los píxels a tu gusto, pero hay ciertos estándares establecidos. A partir de esta condición entramos en el «modo hamburguesa» 🙂
- #hMenu: Al detectar una pantalla pequeña lo primero que hacemos es ocultar el primer elemento del menú <ul id=»hMenu» …>
- #hMenuBtn + label: Ahora debemos mostrar el icono ☰ hamburguesa, pero lo hacemos a través del elemento <label>, dejando el cuadrito del <input> checkbox oculto. Le ponemos un color, relleno, cursor tipo puntero y visualizamos como inline-block.
- #hMenuBtn + label:hover: Para el efecto hover de la hamburgues simplemente cambiamos el color de fondo a verde, acorde a nuestro menú <ul>, <li>, <a>
- #hMenuBtn + label::before: Aquí añadimos un truquito con la propiedad before, insertando el icono ☰ antes del elemento <label>, el cual, al estar vació simplemente consiste en este icono. El tamaño de texto y alto de linea son orientativos y va a gustos, pero es aconsejable hacerlo en
em
para mantener las proporciones generales del texto. - #hMenuBtn:checked ~ #hMenu: Este es el detalle técnico definitivo y donde se crea la mágia. Me sigue costando entenderlo pero lo que hace es lo siguiente. Si el <input> checkbox está activado «checked», (han hecho clic en él) entonces a su hermano general #hMenu que es el primer <
ul id="hMenu" ...
> lo volvemos «visible» condisplay: block
.
Tachan !!!! Increible pero funciona he ?
Menú CSS horizontal o vertical responsive multinivel
A continuación pongo todo el código para los más vagos 😉
<!DOCTYPE>
<html>
<head>
<style>
/* Clase para el contenedor del menú <nav> */
.csMenu {
margin: 0;
padding: 0;
display: block;
font-size: 16px;
overflow: hidden;
background-color: black;
font-family: Arial, Helvetica, sans-serif;
}
/* Contenedores <ul> */
.csMenu ul {
margin: 0;
padding: 0;
display: block;
list-style: none;
}
/* Enlaces */
.csMenu a {
color: white;
display: block;
padding: 0.6em 0.8em;
text-decoration: none;
}
/* Enlaces hover */
.csMenu a:hover {
background-color: green;
}
/* Distribución horizontal */
.mHoriz li {
float: left;
display: block;
}
/* Distribución vertical */
.mVerti li {
width: 10em;
display: block;
text-align: left;
}
/* Submenú infinito */
.subMenu {
position: fixed;
display: none !important;
background-color: green;
box-shadow: 0 0.5em 1em rgba(0, 0, 0, 0.55);
}
/* Submenú infinito hover */
li:hover > .subMenu {
display: block !important;
}
/* Submenú infinito enlaces hover */
.subMenu a:hover {
background-color: black;
}
/* Submenú infinito posicionamiento vertical */
.mVerti .subMenu {
left: 8em;
position: absolute !important;
}
/* Botón tipo hamburguesa en pantallas pequeñas */
#hMenuBtn {
display: none;
}
/* Menú hamburguesa */
@media (max-width: 768px) {
#hMenu {
display: none;
}
#hMenuBtn + label {
color: white;
cursor: pointer;
padding: 0 0.5em;
display: inline-block;
}
#hMenuBtn + label:hover {
background-color: green;
}
#hMenuBtn + label::before {
content: "☰";
font-size: 2rem;
line-height: 1em;
}
#hMenuBtn:checked ~ #hMenu {
display: block;
}
}
</style>
</head>
<body>
<h1>Ejemplo de menú horizontal o vertical multinivel responsive</h1>
<p>Ejemplo de menú horizontal o vertical multinivel responsive</p>
<nav class="csMenu">
<input id="hMenuBtn" type="checkbox" />
<label for="hMenuBtn"></label>
<ul id="hMenu" class="mVerti">
<li><a href="#">Inicio</a></li>
<li><a href="#">Servicios</a></li>
<li><a href="#">Buscador</a></li>
<li><a href="#"">F.A.Q.</a></li>
<li><a href=" #">Utilidades ▼</a>
<ul class="subMenu">
<li><a href="#">Noticias</a></li>
<li><a href="#">Favoritos ►</a>
<ul class="subMenu">
<li><a href="#">Favorito 1</a></li>
<li><a href="#">Favorito 2</a>
<ul class="subMenu">
<li><a href="#">Inicio</a></li>
<li><a href="#">Servicios</a></li>
<li><a href="#">Buscador</a></li>
<li><a href="#"">F.A.Q.</a></li>
<li><a href=" #">Utilidades ▼</a>
<ul class="subMenu">
<li><a href="#">Noticias</a></li>
<li><a href="#">Favoritos ►</a>
<ul class="subMenu">
<li><a href="#">Favorito 1</a></li>
<li><a href="#">Favorito 2</a>
<ul class="subMenu">
<li><a href="#">Favorito 3</a></li>
<li><a href="#">Favorito 4</a></li>
</ul>
</li>
</ul>
</li>
<li><a href="#">Promotores</a></li>
<li><a href="#">Geolocalizador</a></li>
</ul>
</li>
<li><a href="#">Registro</a></li>
<li><a href="#">Entrar</a></li>
</ul>
</li>
</ul>
</li>
<li><a href="#">Promotores</a></li>
<li><a href="#">Geolocalizador</a></li>
</ul>
</li>
<li><a href="#">Registro</a></li>
<li><a href="#">Entrar</a></li>
</ul>
</nav>
</body>
</html>
Como conclusión final debo decir que el menú funciona igual con el alineamiento horizontal (mHoriz) visto en el artículo anterior, aunque no tiene mucho sentido porque en una pantalla pequeña pronto se verá cortado y se transformará en un apelotonamiento vertical del menú, tal y como se comentó en el artículo anterior.
¡ Espero que este artículo sea de vuestro interés !