En este artículo vamos a explicar cómo crear un menú horizontal CSS de 3 niveles de anidación utilizando una lista HTML. La ventaja del método que voy a comentar es lo fácil que resulta implementarlo, ya que sólo habrá que asignar un ID al tag <nav>.

El menú en HTML
El primer paso es construir nuestro menú utilizando una lista HTML no ordenada como en el siguiente ejemplo:
<nav id="csMenu">
<ul>
<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>
<li><a href="#">Noticias</a></li>
<li><a href="#">Favoritos ►</a>
<ul>
<li><a href="#">Favorito 1</a></li>
<li><a href="#">Favorito 2</a></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>
Hay varios detalles a tener en cuenta aquí:
- El elemento semántico <nav id=’csMenu’> hará de contenedor de todo el menú y estará vinculado al CSS mediante su ID. Esto nos permite incidir únicamente en este menú sin afectar a otros tipos de enlaces que podemos tener definididos con CSS
- Los elementos <ul> especifican cada nivel de anidación y, a su vez, hacen de contenedor del submenú que contienen
- Los elementos <li> especifican el posicionamiento de cada celda del menú
- Los elementos <a> especifican el comportamiento y estilo de cada enlace
- Para anidar un menú con otro, añadimos una lista <ul> dentro de un elemento <li> de nivel superior
- Al anidarse los elementos <ul>, <li>, <a> van heredando las propiedades superiores. Esto es muy importante tenerlo presente, para entender porqué aplicamos ciertos estilos en los niveles más profundos
El menú en CSS
Hasta aquí hemos explicado la parte HTML, ahora vamos a explicar los estilos CSS del primer nivel del menú y un aspecto a tener en cuenta es que por defecto los elementos <ul>, <li>, <a> tienen sus propias propiedades.
A veces nos vienen bién y no tenemos que tocar nada, otras veces no nos sirven y debemos modificarlas. En este artículo pongo estilos que se pueden omitir como display: block; pero así queda más claro las propiedades de cada elemento.
/* Estilo de la barra horizontal (nav) */
#csMenu {
display: inline-block;
font-size: 16px;
overflow: hidden;
font-family: Arial, Helvetica, sans-serif;
background-color: black;
}
/* Estilo de bloque del primer nivel */
#csMenu ul {
margin: 0;
padding: 0;
display: block;
list-style: none;
}
/* Estilo de cada celda */
#csMenu ul li {
float: left;
display: block;
}
/* Estilo de cada enlace */
#csMenu ul li a {
color: white;
display: block;
padding: 0.6em 0.8em;
text-decoration: none;
}
/* Estilo de cada enlace (sobre) */
#csMenu ul li a:hover {
background-color: green;
}
Hasta aquí no tiene mucha complicación pero vamos a explicar paso a paso cada regla CSS:
- #csMenu: Afecta directamente a la etiqueta <nav> haciendo que se comporte como un bloque, ocupando todo el espacio horizontal disponible, con un fondo negro. El atributo overflow es un truquillo para mostrar los elementos flotados dentro del elemento contenedor. El font-size y font-family es para modificar el texto a voluntad y comprobar cómo se reajusta todo el menú a su tamaño.
- #csMenu ul: Al primer nivel del elemento <ul> le eliminamos los márgenes y estilo de lista
- #csMenu ul li: Al primer nivel del elemento <li> lo flotamos a la izquierda para obtener el menú en horizontal
- #csMenu ul li a: El texto de los enlaces los mostraremos sin subrallado, en color blanco (sobre negro), con un ligero relleno de espacio y comportamiento de bloque
- #csMenu ul li a:hover: Para conseguir el efecto (hover) del enlace simplemente cambiaremos el color de fondo a verde
Estilos CSS del menú horizontal
De momento el primer nivel es sencillito, vistoso y efectivo, pero al mismo tiempo ya contiene una jerarquía de 4 elementos: <nav> -> <ul> -> <li> -> <a>
Vamos a añadir el segundo nivel de estilos CSS a nuestro menú horizontal
/* Estilo de bloque del segundo nivel */
#csMenu ul li ul {
display: none;
position: absolute;
background-color: green;
box-shadow: 0 0.5em 1em rgba(0, 0, 0, 0.55);
}
/* Estilo de bloque del segundo nivel (sobre) */
#csMenu ul li:hover ul {
display: block;
}
/* Estilo de cada celda */
#csMenu ul li:hover ul li {
float: none;
}
/* Estilo de cada enlace */
#csMenu ul li:hover ul li a {
text-align: left;
white-space: nowrap;
}
/* Estilo de cada enlace (sobre) */
#csMenu ul li:hover ul li a:hover {
background-color: black;
}
Como vemos, los estilos CSS son similares al primer nivel, pero con ciertos matices que vamos a comentar paso a paso:
- #csMenu ul li ul: Aquí establecemos las propiedades de bloque del segundo nivel del menú. A las propiedades heredadas del primer nivel debemos cambiar su visibilidad a «invisible» hasta que no sea seleccionado. También estableceremos su posición en «absoluta» para «sacarlo» del flujo natural de los elementos de la página y del contenedor <nav>. Establecemos su fondo en verde para coincidir con el (hover) al ser seleccionado y por último añadimos una pequeña sombra decorativa
- #csMenu ul li:hover ul: Este estilo es el que nos va a indicar cuando activar el menú de segundo nivel, y será cuando el ratón esté sobre su contenedor <li> superior, entonces simplemente lo hacemos visible. Es importante saber que un elemento «absoluto» se coloca en relación con su primer elemento antecesor posicionado (no estático), que en este caso es su elemento superior <li>, esto nos posiciona el <ul> justo debajo y ya nos está bién.
- #csMenu ul li:hover ul li: Ahora queremos que las celdas de segundo nivel se comporten como un bloque y se distribuyan de forma vertical, por eso eliminamos su estilo float de nivel superior
- #csMenu ul li:hover ul li a: El texto de los enlaces, al mostrarse verticalmente queremos que esté alineado a la izquierda y si hubiera espacios queremos evitar saltos de línea automáticos
- #csMenu ul li:hover ul li a:hover: Por último intercabiamos el color de fondo a negro con el efecto (hover)
Tercer nivel CSS del menú horizontal
Ahora llegamos al tercer y último nivel de anidamiento de nuestro menú y aquí debemos emplear elementos «forzados» para posicionar correctamente el submenú. Sin embargo hay elementos que ya no necesitamos definirlos de nuevo. Vamos a verlo:
/* Estilo de bloque del tercer nivel */
#csMenu ul li ul li ul {
display: none !important;
}
/* Estilo de bloque del tercer nivel (sobre) */
#csMenu ul li ul li:hover ul {
top: 2em;
left: 7em;
display: block !important;
}
En el tercer nivel sólo necesitamos definir los elementos <ul>, puesto que los elementos <li> y <a> ya estan definidos en el segundo nivel y no cambia su comportamiento: el submenu de tercer nivel también será vertical.
- #csMenu ul li ul li ul: En el tercer nivel establecemos las propiedades del bloque <ul> de nuevo a «invisible», pero como en el segundo nivel están siendo visibles por el evento (hover), debemos forzarlo con la instrucción !important
- #csMenu ul li ul li:hover ul: De nuevo el evento (hover) de su contenedor <li> superior establece que el elemento <ul> debe ser visible. Pero como lo acabamos de «forzar» a ser «invisible» tenemos que volver a forzar su visibilidad con !important. En cuanto a su posicionamiento esta vez debemos ajustarlo de forma manual, puesto que queremos que aparezca en el lado derecho de su contenedor <li>. Para ello utilizamos las propiedades (top, left) del su posicionamiento absoluto y las definimos en (em), de esta forma se adaptará al tamaño del texto. Las distancias (top, left) dependen la linea donde queremos que parezca el submenú, la longitud de los textos y también del gusto personal de cada uno.
Menú horizontal CSS de 3 niveles
Como observación final observa que no hemos definido muchas de las propiedades de los niveles superiores porque ya estan heredadas como la sombra, alineamiento del texto, colores, etc.
El código HTML completo es el siguiente:
<!DOCTYPE>
<html>
<head>
<style>
/* Estilo de la barra horizontal (nav) */
#csMenu {
display: inline-block;
font-size: 16px;
overflow: hidden;
font-family: Arial, Helvetica, sans-serif;
background-color: black;
}
/* Estilo de bloque del primer nivel */
#csMenu ul {
margin: 0;
padding: 0;
display: block;
list-style: none;
}
/* Estilo de cada celda */
#csMenu ul li {
float: left;
display: block;
}
/* Estilo de cada enlace */
#csMenu ul li a {
color: white;
display: block;
padding: 0.6em 0.8em;
text-decoration: none;
}
/* Estilo de cada enlace (sobre) */
#csMenu ul li a:hover {
background-color: green;
}
/* Estilo de bloque del segundo nivel */
#csMenu ul li ul {
display: none;
position: absolute;
background-color: green;
box-shadow: 0 0.5em 1em rgba(0, 0, 0, 0.55);
}
/* Estilo de bloque del segundo nivel (sobre) */
#csMenu ul li:hover ul {
display: block;
}
/* Estilo de cada celda */
#csMenu ul li:hover ul li {
float: none;
}
/* Estilo de cada enlace */
#csMenu ul li:hover ul li a {
text-align: left;
white-space: nowrap;
}
/* Estilo de cada enlace (sobre) */
#csMenu ul li:hover ul li a:hover {
background-color: black;
}
/* Estilo de bloque del tercer nivel */
#csMenu ul li ul li ul {
display: none !important;
}
/* Estilo de bloque del tercer nivel (sobre) */
#csMenu ul li ul li:hover ul {
top: 2em;
left: 7em;
display: block !important;
}
</style>
</head>
<body>
<h1>Menú horizontal</h1>
<p>Ejemplo de menú horizontal hasta 3 niveles</p>
<nav id="csMenu">
<ul>
<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>
<li><a href="#">Noticias</a></li>
<li><a href="#">Favoritos ►</a>
<ul>
<li><a href="#">Favorito 1</a></li>
<li><a href="#">Favorito 2</a></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>
Hasta aquí hemos explicado cómo hacer un menú horizontal de 3 niveles con HTML y CSS utilizando una lista de elementos <ul>, <li>, <a>. Podemos modificar el CSS y obtener un menú vertical de tres niveles, añadir más niveles de anidamiento, utilizar clases CSS en vez de tags, etc.
Si te ha parecido interesante no te lo pierdas en el siguiente artículo: https://fashehlabs.com/css/menu-horizontal-o-vertical-multinivel-con-css/.
¡ Espero que este artículo sea de vuestro interés !
He buscado en varios blocks como hacer este tipo de menu, y este ha sido el mas facil de entender y modificar, excelente contenido!!
Hola Lina,
muchas gracias por tu apoyo y me alegro que este artículo te haya sido de utilidad 🙂
Un saludo!