Seguramente a lo largo de tu vida como internauta has navegado por diferentes páginas web y al hacerlo desde tu computadora te has encontrado con un menú típico en la parte superior de la página, pero… Cuando decides entrar a esa misma página desde tu celular ves que ese menú ya no está y ha sido reemplazado por un botón con tres líneas que cuando lo presionas hace que mágicamente aparezca el menú que antes estaba oculto.
Bueno, déjame contarte que en realidad no aparece mágicamente y aquí la magia la hacemos tú y yo al dominar los lenguajes de la web.
¿Sabes cómo se crean estos menús? Algunas personas utilizan JavaScript para dotar de funcionalidades al botón y que al ser presionado muestre u oculte el menú. Pero tú y yo no lo haremos así, usar JavaScript para esto es cosa del pasado, lo ideal es hacer uso únicamente de CSS y bueno HTML, claro.
Vamos por pasos y empecemos a darle forma a este menú que te será de utilidad para seguramente más de uno de tus proyectos.
1. Creación la estructura base del HTML
Escoge tu herramienta favorita para iniciar con el proyecto, puedes emplear tu Visual Studio Code de confianza o quizás quieras probar CodeSandbox o incluso CodePen, el que elijas está bien, asegúrate de usar con el que más a gusto te sientas.
Si ya elegiste la herramienta que utilizaras para crear el menú, iniciemos creando la estructura básica para trabajar en HTML, la cual es la siguiente:
<htmllang="es">
<head>
<metacharset="UTF-8">
<metahttp-equiv="X-UA-Compatible"content="IE=edge">
<metaname="viewport"content="width=device-width, initial-scale=1.0">
<title>Platzi: Menu responsivetitle>
head>
<body>
body>
html>
Un truco para generar toda esta estructura de forma muy rápida es escribir !
seguido de un tab
, pruébalo y verás como tu IDE crea todo de forma automática.
2. Creación la estructura HTML del menú
Con la estructura inicial del HTML lista, ahora hay que definir la estructura pero del menú. Recuerda que HTML es semántico y tiene su propia etiqueta para los menús de navegación, la cual es y por supuesto será la que contenga todos los elementos que vamos a utilizar.
Pero antes de continuar con el código, quiero que tengas en mente que el menú que vamos a maquetar será el de la imagen siguiente. Me gustaría que intentaras definir los elementos HTML que lo conforman. Inténtalo antes de seguir leyendo y recuerda añadir los elementos que creas necesarios para su versión móvil.

¿Ya hiciste tu propuesta del menú? Bueno, la mía es esta:
<navclass="nav">
<inputtype="checkbox"name=""id="nav__checkbox"class="nav__checkbox" />
<labelfor="nav__checkbox"class="nav__toggle">
<svgclass="menu"viewBox="0 0 448 512"width="100"title="bars">
<path
d="M16 132h416c8.837 0 16-7.163 16-16V76c0-8.837-7.163-16-16-16H16C7.163 60 0 67.163 0 76v40c0 8.837 7.163 16 16 16zm0 160h416c8.837 0 16-7.163 16-16v-40c0-8.837-7.163-16-16-16H16c-8.837 0-16 7.163-16 16v40c0 8.837 7.163 16 16 16zm0 160h416c8.837 0 16-7.163 16-16v-40c0-8.837-7.163-16-16-16H16c-8.837 0-16 7.163-16 16v40c0 8.837 7.163 16 16 16z" />
svg>
<svgclass="close"viewBox="0 0 384 512"width="100"title="times">
<path
d="M242.72 256l100.07-100.07c12.28-12.28 12.28-32.19 0-44.48l-22.24-22.24c-12.28-12.28-32.19-12.28-44.48 0L176 189.28 75.93 89.21c-12.28-12.28-32.19-12.28-44.48 0L9.21 111.45c-12.28 12.28-12.28 32.19 0 44.48L109.28 256 9.21 356.07c-12.28 12.28-12.28 32.19 0 44.48l22.24 22.24c12.28 12.28 32.2 12.28 44.48 0L176 322.72l100.07 100.07c12.28 12.28 32.2 12.28 44.48 0l22.24-22.24c12.28-12.28 12.28-32.19 0-44.48L242.72 256z" />
svg>
label>
<ulclass="nav__menu">
<liclass="menu__logo">
<imgsrc="images/logo1.webp"alt="" />
<imgsrc="images/logo2.webp"alt="" />
li>
<li><ahref="#">Clasesa>li>
<li><ahref="#">Bloga>li>
<li><ahref="#">Foroa>li>
ul>
nav>
No te asustes, vamos a desmenuzarlo para ir entendiendo la estructura y por qué está definida de esta manera.
Primero está el que es de tipo
checkbox
, esto es así porque cuando estemos en la vista móvil el estado del checkbox
, ya sea true
o false
, indicará si el menú debe mostrarse o no.
type="checkbox" name="" id="nav__checkbox"class="nav__checkbox" />
El segundo elemento presente es el que pertenece al
anterior, este elemento nos da la posibilidad de jugar con él para mostrar los iconos del menú. Tenemos la
X
para cerrarlo o el icono de hamburguesa para abrirlo en la versión móvil y es por esto que dentro de esta etiqueta se incluyeron los SVG (Gráficos Vectoriales Escalables por sus siglas en inglés) de ambos iconos.
<labelfor="nav__checkbox"class="nav__toggle">
<svgclass="menu"viewBox="0 0 448 512"width="100"title="bars">
<path
d="M16 132h416c8.837 0 16-7.163 16-16V76c0-8.837-7.163-16-16-16H16C7.163 60 0 67.163 0 76v40c0 8.837 7.163 16 16 16zm0 160h416c8.837 0 16-7.163 16-16v-40c0-8.837-7.163-16-16-16H16c-8.837 0-16 7.163-16 16v40c0 8.837 7.163 16 16 16zm0 160h416c8.837 0 16-7.163 16-16v-40c0-8.837-7.163-16-16-16H16c-8.837 0-16 7.163-16 16v40c0 8.837 7.163 16 16 16z" />
svg>
<svgclass="close"viewBox="0 0 384 512"width="100"title="times">
<path
d="M242.72 256l100.07-100.07c12.28-12.28 12.28-32.19 0-44.48l-22.24-22.24c-12.28-12.28-32.19-12.28-44.48 0L176 189.28 75.93 89.21c-12.28-12.28-32.19-12.28-44.48 0L9.21 111.45c-12.28 12.28-12.28 32.19 0 44.48L109.28 256 9.21 356.07c-12.28 12.28-12.28 32.19 0 44.48l22.24 22.24c12.28 12.28 32.2 12.28 44.48 0L176 322.72l100.07 100.07c12.28 12.28 32.2 12.28 44.48 0l22.24-22.24c12.28-12.28 12.28-32.19 0-44.48L242.72 256z" />
svg>
label>
El último elemento es el
, el cual no es más que una lista desordenada que contiene los elementos que servirán para la navegación del sitio web que contenga el menú.
class="nav__menu">
<liclass="menu__logo">
<imgsrc="https://raw.githubusercontent.com/alexcamachogz/random_images/main/Platzi-logo.webp"alt="Platzi-isotipo" />
<imgsrc="https://raw.githubusercontent.com/alexcamachogz/random_images/main/platzi-name.webp"alt="Platzi-logotipo" />
li>
<li><ahref="#">Clasesa>li>
<li><ahref="#">Bloga>li>
<li><ahref="#">Foroa>li>
ul>
De momento el proyecto luce así 👇🏻

Pero no te preocupes, ahora que ya está lista la estructura del menú, el siguiente paso es trabajar con los estilos y mejorar la presentación.
3. Declaración de las variables y definición de los estilos generales
Antes de empezar a jugar con el CSS lo ideal es definir las variables con las que se van a estar trabajando, por ejemplo los colores, así es más fácil utilizarlos a lo largo del proyecto.
Las variables en CSS se declaran por lo general dentro del selector :root
para que sean globales. En este caso definí los tres colores que usaré en todo el menú dentro de este selector. Siéntete libre de utilizar tus colores favoritos o los que creas convenientes.
:root {
--primary: #121f3d;
--white: #fff;
--gray: #2a324b;
}
El siguiente paso es restablecer los valores de los elementos, ya que los navegadores tienden a incluir algunos estilos por defecto. La manera más apropiada de restablecer estos valores es hacer uso de una librería como Normalize.css, te recomiendo usarla para tus proyectos.
En este caso no haré uso de ella para simplificar el código y simplemente definiré que los margin
y padding
de todos los elementos sean cero.
Por otro lado, el box-sizing: border-box
le dice al navegador que tome en cuenta los border
y padding
para el width
y height
de los elementos.
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
Continuando con los estilos generales, para el simplemente hay que definir propiedades relacionadas a la fuente y al color de letra y de fondo.
body {
font-family: sans-serif;
font-weight: lighter;
color: var(--white);
background-color: var(--primary);
height: 100vh;
}
El único estilo que se le agregará al .nav
que es el elemento es un borde inferior, que si recuerdas la imagen del menú es esa línea gris tenue para separar al menú de otros elementos.
.nav {
border-bottom: 1px solid var(--gray);
}
Para terminar con los estilos generales, ocultaremos el al cual le pusimos la clase
.nav__checkbox
para que no se muestre en el navegador, ya que de este input solo nos interesa su funcionalidad y no la visibilidad del elemento.
.nav__checkbox {
display: none;
}
Ahora el proyecto luce así, ya podemos empezar a notar los primeros estilos 👇🏻

4. Crear los estilos para la etiqueta label
La etiqueta como ya viste en el HTML es la que contiene los iconos con los que se interactuará cuando el menú esté en su versión móvil. Por lo tanto, se define el
position
como absolute
para poder cambiar su posición por defecto a una más adecuada.
.nav__toggle {
position: absolute;
cursor: pointer;
margin: 01rem;
right: 0;
}
Por otro lado, los SVG son demasiado grandes, así que cambiamos su tamaño y el color al blanco que está definido en las variables declaradas al inicio. De esta forma los iconos se verán más integrados al diseño definido.
.nav__togglesvg {
width: 1rem;
fill: var(--white);
}
Como por defecto el icono que se va a ver es el del menú, se oculta el icono de cierre con la propiedad de display
en none
.
.nav__toggle.close {
display: none;
}
Para finalizar con los estilos de esta sección, a ambos iconos se les agrega un margin-top
para mejorar el espaciado entre el resto de elementos.
.nav__toggle.close,
.nav__toggle.menu {
margin-top: 0.3rem;
}
Con los estilos del completados, el menú empieza a lucir como un menú👇🏻

5. Crear los estilos para el menú
Toca trabajar con los estilos del menú, el cual no es otra cosa que la lista desordenada que contenía los ítems de navegación.
El primer paso es cambiar la orientación de los ítems de horizontal a vertical, para esto se usa la propiedad de display: flex
acompañada de flex-direction: column
como se muestra en los estilos.
.nav__menu {
align-items: center;
display: flex;
flex-direction: column;
gap: 2rem;
margin: 1rem;
}
Lo siguiente es remover los *
propios de las listas con la propiedad list-style-type
en none
y ocultar todos los ítems que después se mostrarán con la interacción del menú.
.nav__menuli {
display: none;
list-style-type: none;
}
Como puedes notar el logo de Platzi había quedado centrado porque también era un ítem de la lista y además desapareció, pero este siempre debe de estar visible porque es parte de la marca.
Para hacerlo visible y posicionarlo a la izquierda como estaba anteriormente se hace uso de la pseudo-clase :first-child
para afectarlo únicamente a él por ser el primer elemento. Dentro del esta declaración el display
es cambiado a block
y se indica que el margin-right
debe de ser auto
.
Listo, ahora el logo de Platzi sigue siendo visible y está posicionado correctamente.
.nav__menuli:first-child {
display: block;
margin-right: auto;
}
Antes de desaparecer los ítems de la lista, al ser enlaces tenían el estilo y color predeterminado lo cual no es homogéneo con el diseño propuesto. Para ajustar esto solo hay que cambiar el color de la etiqueta y definir el
text-decoration
como none
.
.nav__menua {
color: inherit;
font-size: 1.1rem;
text-decoration: none;
}
Para finalizar con los estilos del menú, el icono de hamburguesa se ve pequeño en comparación del logo, lo cual es muy fácil de resolver, únicamente hay que ajustar el height
de este elemento.
.menu__logo {
height: 30px;
}
.menu__logoimg {
height: 100%;
}
Con esto ya tenemos el menú listo, si has seguido los pasos hasta el momento tu menú debe de lucir así 👇🏻

6. Incluir la interacción del menú con el checkbox
El menú ya está construido, ahora cuando el usuario de clic al icono del menú lo que debe de pasar es que el menú se despliegue y se muestren los ítems que ocultamos en el paso anterior.
Seguramente te estás preguntando cómo podemos hacer eso sin tener un EventListener
de JavaScript escuchando, pero créeme que no es necesario.
Al estar usando un de tipo
checkbox
se puede validar su estado con la pseudo-clase :checked
, la cual indica si está seleccionado o no, como si fuera un if
en cualquier otro lenguaje de programación.
Sabiendo esto podemos decir que si el checkbox
esta seleccionado, el elemento ul.nav__menu li
que no es otra cosa que nuestra lista de ítems debe de tener su display
a block
. Todo esto se representa en el código siguiente.
#nav__checkbox:checked ~ ul.nav__menuli {
display: block;
}
De igual forma si está seleccionado, al icon que tiene la clase .close
también le cambiamos su display
a block
, para que se muestre la X
cuando los ítems se muestren.
#nav__checkbox:checked ~ label.nav__toggle.close {
display: block;
}
Y ya por último cambiamos el display
del .menu
a none
para que solo se muestre el icono de X
y se oculte el de hamburguesa.
#nav__checkbox:checked ~ label.nav__toggle.menu {
display: none;
}
Con estos tres simples bloques se consigue que el menú aparezca y desaparezca como si fuera magia, pero ahora tu sabes que no es magia, simplemente dominas CSS.

7. Definir las media queries para que el menú sea responsivo
Y ahora sí, como último paso toca crear las media queries para que en dispositivos grandes se muestre el menú extendido y no el desplegable.
Para esto hay que definir una media query que a partir de los 560px
de width
aplique los estilos que queramos, como cambiar los display
de algunos elementos y también el flex-direction
del menú a row
para que ahora los ítems estén en horizontal.
@media only screen and (min-width: 560px) {
.nav__toggle {
display: none;
}
.nav__menu {
flex-direction: row;
}
.nav__menuli {
display: block;
}
}
Una vez agregados estos estilos si visualizamos el menú en una ventana pequeña se mostrará el menú desplegable, si lo visualizamos en una mayor a 560px
, entonces aparecerá el menú extendido.

Listo, con esto ya sabes crear un menú completamente responsivo e interactivo con únicamente CSS y HTML, la magia ha sido develada y los poderes ahora son tuyos para dominar la web en dispositivos pequeños y grandes.
En resumen
Este mismo menú lo realicé en un segmento del live llamado “Profes a prueba” en donde tenía únicamente diez minutos para completar el reto, si quieres verme en contra reloj construyendo este menú puedes hacerlo aquí 👇🏻

Si lo que quieres es jugar un poco con el código que hicimos a lo largo de este tutorial te dejo varias opciones.
La primera es un pen en CodePen, si te gusta hacer uso de esta herramienta, seguramente está será la mejor forma de que pruebes el menú que hicimos. Como segunda opción te dejo un sandbox en CodeSandbox si prefieres esta herramienta. Por último pero no menos importante también te dejo el código en un repositorio de GitHub para que lo puedas clonar.
Si quieres dominar toda la magia del CSS y que ningún tamaño de pantalla sea un problema para ti puedes tomar el curso de Responsive Design: Maquetación Mobile First y no te olvides de practicar todo lo aprendido.
Y ya por último, déjame en los comentarios si te animaste a crear tu propio menú y cuáles fueron los resultados, recuerda que aquí la creatividad no tiene limites.
Curso de Responsive Design: Maquetación Mobile First