Juneikerc.com

Cómo hacer un menú hamburguesa con html, css y javascript

imagen destacada del post: Cómo hacer un menú hamburguesa con html, css y javascript

Desde que nacieron los dispositivos móviles este tipo de menús son los más comunes en toda la web y en este tutorial te enseñare como crear uno desde cero usando un poco de css y javascript.

Estructura html para el menú hamburguesa responsive

html
<header class="main-header">
<a class="main-logo" href="/">
<strong>Logo</strong>
</a>
<nav id="nav" class="main-nav">
<div class="nav-links">
<a class="link-item" href="#">Link1</a>
<a class="link-item" href="#">Link2</a>
<a class="link-item" href="#">Link3</a>
<a class="link-item" href="#">Link4</a>
</div>
</nav>
<button id="button-menu" class="button-menu">
<span></span>
<span></span>
<span></span>
</button>
</header>

Explicación paso a paso código de nuestro nav responsive

  1. Definimos un header clásico con un enlace que debiera ser el logo de la web pero para efectos prácticos de este tutorial coloco el nombre de esta web. Importante nunca pongas el logo como h1, por temas de SEO esta etiqueta debe estar reservada para el título principal de la página
  2. Agregamos una etiqueta nav con un div que servirá como contenedor de 4 enlaces de navegación.
  3. Por último una etiqueta button con tres span que servirán para dibujar el menú css

Agregando css para estilizar nuestro menú hamburguesa responsive

Empezamos reseteando todo los estilos del documento:

css
* {
margin: 0;
padding: 0;
}

Ahora aplicamos algunos estilos sencillos al header para separar el logo y la navegación.

css
.main-header {
height: 50px;
display: flex;
justify-content: space-between;
align-items: center;
background-color: white;
padding: 0 0.4rem;
}
.main-logo {
color: black;
font-size: 32px;
text-decoration: none;
}

Empezamos a trabajar con la etiqueta nav diseñando primero los estilos para móviles más adelante agregaremos una media query para el diseño de escritorio.

Con el siguiente css lograremos que el nav ocupe todo el espacio de la ventana del navegador cuando este abierto y además que se mantenga fijo cuándo el usuario haga scroll, no queremos que el menú este siempre visible así que con la propiedad margin-left: -100%; escondemos toda la navegación de la ventana principal.

También agregamos una propiedad transition: all 0.2s linear; para que nuestro elemento no se muestre y oculte de forma poco natural. Además establecemos el z-index en 100 para que la navegación siempre este por encima del resto de elementos de la página.

La etiqueta nav tendrá un color de fondo semitransparente que será diferente al background del contenedor de los enlaces de navegación.

Por último declaramos que cuando la etiqueta nav tenga la clase show el margin-left sea 0 haciendo aparecer nuestra navegación. Más adelante haremos toda la magia con javascript.

css
.main-nav {
position: fixed;
top: 0;
left: 0;
height: 100vh;
width: 100%;
margin-left: -100%;
transition: all 0.2s linear;
z-index: 100;
background-color: rgba(0, 0, 0, 0.7);
}
.main-nav.show {
margin-left: 0;
}

El contenedor de los enlaces tendrá un background blanco y establecemos un flex-direction:column; para poner los enlaces uno abajo del otro.

Asignamos un width de 70% para que el contenedor de los enlaces no ocupe todo el espacio del nav, por otra parte la altura si la declaramos en 100% para que abarque toda la pantalla.

Por último unos estilos sencillos para cada enlace.

css
.nav-links {
background-color: rgb(250, 250, 250);
display: flex;
flex-direction: column;
width: 70%;
height: 100%;
align-items: center;
justify-content: flex-start;
}
.link-item {
margin-top: 2rem;
color: #444444;
text-decoration: none;
font-weight: bold;
position: relative;
}

Queremos que el botón del menú tenga un z-index: 200; para que sea clickable por encima de la navegación.

css
.button-menu {
z-index: 200;
width: 40px;
height: 40px;
border: none;
display: flex;
background: none;
flex-direction: column; /* Pondrá un span debajo del otro*/
align-items: center;
justify-content: center;
cursor: pointer;
}
/*
Dibujamos una línea recta por cada span creando el tipico menu hamburguesa
*/
.button-menu span {
width: 37px;
height: 4px;
margin-bottom: 5px;
position: relative;
background: #444444;
border-radius: 3px;
transform-origin: 4px 0px;
transition: all 0.2s linear;
}
/*
con los span dibujamos un icono de cerrar
para mostrar cuándo la navegación este abierta
*/
.button-menu.close span {
opacity: 1;
transform: rotate(45deg) translate(0px, 0px);
background: #ffffff;
}
.button-menu.close span:nth-child(2) {
transform: rotate(-45deg) translate(-8px, 5px);
}
.button-menu.close span:nth-child(3) {
display: none;
}

A continuación junto con todo el código encontrarás las media querys para mostrar el menú de forma diferente en desktop

Código css completo de nuestro header y menú responsive

css
* {
margin: 0;
padding: 0;
}
.main-header {
height: 50px;
display: flex;
justify-content: space-between;
align-items: center;
background-color: white;
padding: 0 0.4rem;
}
.main-logo {
color: black;
font-size: 32px;
text-decoration: none;
}
.main-nav {
position: fixed;
top: 0;
left: 0;
height: 100vh;
width: 100%;
margin-left: -100%;
transition: all 0.2s linear;
background-color: rgba(0, 0, 0, 0.7);
z-index: 100;
}
.main-nav.show {
margin-left: 0;
}
.nav-links {
background-color: rgb(250, 250, 250);
display: flex;
flex-direction: column;
width: 70%;
height: 100%;
align-items: center;
justify-content: flex-start;
}
.link-item {
margin-top: 2rem;
color: #444444;
text-decoration: none;
font-weight: bold;
position: relative;
}
.link-item::after {
position: absolute;
content: "";
background-color: black;
bottom: -5px;
left: 0;
width: 0%;
height: 3px;
transition: 0.3s ease all;
}
.link-item:hover::after {
width: 100%;
}
.button-menu {
z-index: 200;
width: 40px;
height: 40px;
border: none;
display: flex;
background: none;
flex-direction: column;
align-items: center;
justify-content: center;
cursor: pointer;
}
.button-menu span {
width: 37px;
height: 4px;
margin-bottom: 5px;
position: relative;
background: #444444;
border-radius: 3px;
transform-origin: 4px 0px;
transition: all 0.2s linear;
}
.button-menu.close span {
opacity: 1;
transform: rotate(45deg) translate(0px, 0px);
background: #ffffff;
}
.button-menu.close span:nth-child(2) {
transform: rotate(-45deg) translate(-8px, 5px);
}
.button-menu.close span:nth-child(3) {
display: none;
}
@media screen and (min-width: 768px) {
.button-menu {
display: none;
}
.main-logo {
flex-basis: 30%;
}
.main-nav {
position: static;
margin-left: 0;
flex-basis: 70%;
height: 100%;
}
.nav-links {
width: 100%;
flex-direction: row;
flex-wrap: wrap;
align-items: center;
justify-content: flex-end;
background: white;
}
.link-item {
display: inline-block;
margin-top: 0;
margin-right: 2rem;
}
}

Terminamos con un par de líneas de javascript para darle interactividad al menú

js
// seleccionamos los dos elementos que serán clickables
const toggleButton = document.getElementById("button-menu");
const navWrapper = document.getElementById("nav");
/*
cada ves que se haga click en el botón
agrega y quita las clases necesarias
para que el menú se muestre.
*/
toggleButton.addEventListener("click", () => {
toggleButton.classList.toggle("close");
navWrapper.classList.toggle("show");
});
/*
Cuándo se haga click fuera del contenedor de enlaces
el menú debe esconderse.
*/
navWrapper.addEventListener("click", e => {
if (e.target.id === "nav") {
navWrapper.classList.remove("show");
toggleButton.classList.remove("close");
}
});

Resultado del menú hamburguesa en codepen

Juneiker Castillo freelance web developer

Soy Juneiker Castillo, un desarrollador web frontend apasionado por la programación y la creación de sitios web modernos rápidos y escalables, en fin un friki 🤓 de javascript enamorado de react js ⚛️.

Sobre mi