Saltar al contenidoIr al contenido
Cómo crear un navbar responsive con HTML, CSS y JavaScript
Tutoriales

Cómo crear un navbar responsive con HTML, CSS y JavaScript

Un navbar responsive es una barra de navegación que se adapta correctamente a diferentes tamaños de pantalla.

En pantallas grandes, los enlaces pueden mostrarse de forma horizontal. En dispositivos móviles, los enlaces pueden ocultarse y mostrarse mediante un botón de tipo hamburguesa.

En esta guía veremos cómo crear un navbar moderno, adaptable y con animaciones usando HTML, CSS y un poco de JavaScript.

Qué vamos a crear

El objetivo es construir una barra de navegación que funcione de la siguiente manera:

  • En pantallas grandes muestra el logo y los enlaces del menú.
  • En pantallas pequeñas oculta los enlaces.
  • Muestra un botón de menú hamburguesa en móviles.
  • Al hacer clic en el botón, el menú se despliega con animación.
  • El icono cambia de hamburguesa a una X.
  • Los enlaces aparecen uno por uno con efecto escalonado.
  • Al hacer clic en un enlace, el menú se cierra automáticamente.

Archivos necesarios

Para este proyecto podemos trabajar con tres archivos:

  • index.html
  • estilo.css
  • script.js

El archivo HTML tendrá la estructura del navbar, el CSS se encargará del diseño y las animaciones, y JavaScript agregará la funcionalidad del menú desplegable.

Estructura HTML del navbar

Lo primero será crear la estructura básica dentro del archivo index.html.

Usaremos la etiqueta header para representar la cabecera principal de la página. Dentro colocaremos una etiqueta nav, que representa la barra de navegación.

<header>
    <nav>
        <div class="nav_container">
            <a href="#" class="logo">Mi Sitio</a>

            <button class="menu_btn" id="menu_btn" aria-expanded="false">☰</button>

            <ul class="nav_links" id="nav_links">
                <li><a href="#inicio">Inicio</a></li>
                <li><a href="#servicios">Servicios</a></li>
                <li><a href="#portafolio">Portafolio</a></li>
                <li><a href="#contacto">Contacto</a></li>
            </ul>
        </div>
    </nav>
</header>

En esta estructura tenemos un logo, un botón para móviles y una lista de enlaces.

Por qué usar header y nav

La etiqueta header ayuda a definir la cabecera de la página.

La etiqueta nav indica que dentro de ese bloque se encuentra la navegación principal del sitio.

Usar etiquetas semánticas mejora la organización del código y ayuda a que la estructura sea más clara.

Logo del sitio

El logo se crea con una etiqueta a.

<a href="#" class="logo">Mi Sitio</a>

En este caso usamos href="#" porque el enlace no apunta a una página específica. También agregamos la clase logo para darle estilo con CSS.

Botón de menú hamburguesa

El botón del menú será visible en pantallas pequeñas.

<button class="menu_btn" id="menu_btn" aria-expanded="false">☰</button>

La clase menu_btn servirá para aplicar estilos y el ID menu_btn permitirá seleccionar el botón desde JavaScript.

El atributo aria-expanded ayuda a mejorar la accesibilidad, indicando si el menú está abierto o cerrado.

Lista de enlaces

Los enlaces del menú se colocan dentro de una lista ul.

<ul class="nav_links" id="nav_links">
    <li><a href="#inicio">Inicio</a></li>
    <li><a href="#servicios">Servicios</a></li>
    <li><a href="#portafolio">Portafolio</a></li>
    <li><a href="#contacto">Contacto</a></li>
</ul>

Cada enlace apunta a una sección del sitio usando un identificador con numeral.

CSS base del proyecto

Ahora pasamos al archivo estilo.css.

Primero aplicamos un reseteo básico para eliminar márgenes y rellenos por defecto.

* {
    margin: 0;
    padding: 0;
    box-sizing: border-box;
    font-family: Arial, Helvetica, sans-serif;
}

Esto ayuda a que el diseño se vea más consistente en diferentes navegadores.

Estilos del nav

Ahora damos estilo a la etiqueta nav.

nav {
    background-color: #000;
    padding: 1rem 2rem;
    box-shadow: 0 2px 10px rgba(0, 0, 0, .3);
}

Con esto agregamos un fondo oscuro, espacio interno y una sombra ligera.

Contenedor del navbar

El contenedor principal se organiza con Flexbox.

.nav_container {
    max-width: 1000px;
    margin: 0 auto;
    display: flex;
    align-items: center;
    justify-content: space-between;
}

Con justify-content: space-between colocamos el logo a un lado y los enlaces al otro.

Estilos del logo

El logo tendrá texto blanco, negrita y un tamaño mayor.

.logo {
    color: #fff;
    font-weight: bold;
    font-size: 1.5rem;
    text-decoration: none;
}

Estilos de los enlaces

La lista de enlaces se muestra en horizontal usando Flexbox.

.nav_links {
    display: flex;
    gap: 2rem;
    list-style: none;
    transition: all .3s ease;
}

.nav_links a {
    color: #fff;
    text-decoration: none;
    font-weight: 500;
    transition: all .3s ease;
}

Con gap agregamos separación entre los enlaces y con list-style: none quitamos los puntos de la lista.

Efecto hover en los enlaces

Podemos agregar un pequeño efecto al pasar el mouse sobre los enlaces.

.nav_links a:hover {
    opacity: .75;
    transform: translateY(-2px);
}

Este efecto hace que el enlace se vea un poco más transparente y se eleve ligeramente.

Estilos del botón de menú

El botón del menú será visible solo en pantallas pequeñas. Primero le damos estilo general.

.menu_btn {
    display: none;
    background: none;
    border: none;
    color: #fff;
    font-size: 2rem;
    cursor: pointer;
}

Usamos display: none para ocultarlo en pantallas grandes.

Crear el diseño responsive

Para adaptar el navbar a pantallas pequeñas usamos una media query.

En este caso, aplicaremos cambios cuando el ancho de la pantalla sea menor o igual a 768px.

@media (max-width: 768px) {
    .menu_btn {
        display: block;
    }
}

Cuando la pantalla sea pequeña, el botón de menú se mostrará.

Menú desplegable en móviles

Dentro de la misma media query, modificamos la lista de enlaces.

@media (max-width: 768px) {
    .menu_btn {
        display: block;
    }

    .nav_links {
        position: fixed;
        top: 70px;
        left: 0;
        width: 100%;
        background-color: #000;
        flex-direction: column;
        align-items: center;
        padding: 2rem 0;
        clip-path: circle(0% at 100% 0);
        pointer-events: none;
    }

    .nav_links.active {
        clip-path: circle(150% at 100% 0);
        pointer-events: auto;
    }
}

Con position: fixed colocamos el menú debajo del navbar. Con clip-path creamos un efecto de apertura circular.

Cuando el menú tiene la clase active, el círculo se expande y el menú queda visible.

Animación de los elementos del menú

Para que los enlaces aparezcan con una animación suave, primero los ocultamos.

@media (max-width: 768px) {
    .nav_links li {
        opacity: 0;
        transform: translateY(20px);
        transition: all .3s ease;
    }

    .nav_links.active li {
        opacity: 1;
        transform: translateY(0);
    }
}

Cuando el menú está activo, los elementos vuelven a su posición original y se muestran.

Efecto escalonado con transition-delay

Para que los enlaces aparezcan uno detrás de otro, agregamos retrasos individuales.

@media (max-width: 768px) {
    .nav_links.active li:nth-child(1) {
        transition-delay: .1s;
    }

    .nav_links.active li:nth-child(2) {
        transition-delay: .2s;
    }

    .nav_links.active li:nth-child(3) {
        transition-delay: .3s;
    }

    .nav_links.active li:nth-child(4) {
        transition-delay: .4s;
    }
}

Así cada enlace inicia su animación con una pequeña diferencia de tiempo.

CSS completo del navbar

* {
    margin: 0;
    padding: 0;
    box-sizing: border-box;
    font-family: Arial, Helvetica, sans-serif;
}

nav {
    background-color: #000;
    padding: 1rem 2rem;
    box-shadow: 0 2px 10px rgba(0, 0, 0, .3);
}

.nav_container {
    max-width: 1000px;
    margin: 0 auto;
    display: flex;
    align-items: center;
    justify-content: space-between;
}

.logo {
    color: #fff;
    font-weight: bold;
    font-size: 1.5rem;
    text-decoration: none;
}

.nav_links {
    display: flex;
    gap: 2rem;
    list-style: none;
    transition: all .3s ease;
}

.nav_links a {
    color: #fff;
    text-decoration: none;
    font-weight: 500;
    transition: all .3s ease;
}

.nav_links a:hover {
    opacity: .75;
    transform: translateY(-2px);
}

.menu_btn {
    display: none;
    background: none;
    border: none;
    color: #fff;
    font-size: 2rem;
    cursor: pointer;
}

@media (max-width: 768px) {
    .menu_btn {
        display: block;
    }

    .nav_links {
        position: fixed;
        top: 70px;
        left: 0;
        width: 100%;
        background-color: #000;
        flex-direction: column;
        align-items: center;
        padding: 2rem 0;
        clip-path: circle(0% at 100% 0);
        pointer-events: none;
    }

    .nav_links.active {
        clip-path: circle(150% at 100% 0);
        pointer-events: auto;
    }

    .nav_links li {
        opacity: 0;
        transform: translateY(20px);
        transition: all .3s ease;
    }

    .nav_links.active li {
        opacity: 1;
        transform: translateY(0);
    }

    .nav_links.active li:nth-child(1) {
        transition-delay: .1s;
    }

    .nav_links.active li:nth-child(2) {
        transition-delay: .2s;
    }

    .nav_links.active li:nth-child(3) {
        transition-delay: .3s;
    }

    .nav_links.active li:nth-child(4) {
        transition-delay: .4s;
    }
}

Agregar funcionalidad con JavaScript

Ahora falta hacer que el botón abra y cierre el menú.

Para eso usamos JavaScript y seleccionamos los elementos que vamos a manipular.

const menuBtn = document.getElementById("menu_btn");
const navLinks = document.getElementById("nav_links");

Con estas constantes tenemos acceso al botón y a la lista de enlaces.

Abrir y cerrar el menú

Agregamos un evento click al botón.

menuBtn.addEventListener("click", () => {
    navLinks.classList.toggle("active");
});

Cada vez que el usuario haga clic, se alternará la clase active. Si la clase existe, el menú se muestra. Si no existe, se oculta.

Cambiar el icono del botón

También podemos cambiar el icono de hamburguesa a una X cuando el menú esté abierto.

menuBtn.addEventListener("click", () => {
    navLinks.classList.toggle("active");

    if (navLinks.classList.contains("active")) {
        menuBtn.textContent = "✕";
        menuBtn.setAttribute("aria-expanded", "true");
    } else {
        menuBtn.textContent = "☰";
        menuBtn.setAttribute("aria-expanded", "false");
    }
});

Además de cambiar el icono, actualizamos el atributo aria-expanded para mejorar la accesibilidad.

Cerrar el menú al hacer clic en un enlace

En móviles, es útil que el menú se cierre automáticamente cuando el usuario selecciona una opción.

Primero seleccionamos todos los enlaces dentro del menú.

const links = document.querySelectorAll("#nav_links a");

Luego recorremos cada enlace con forEach y agregamos un evento click.

links.forEach((link) => {
    link.addEventListener("click", () => {
        navLinks.classList.remove("active");
        menuBtn.textContent = "☰";
        menuBtn.setAttribute("aria-expanded", "false");
    });
});

Así, cuando el usuario toca un enlace, el menú se oculta y el botón vuelve al icono de hamburguesa.

JavaScript completo

const menuBtn = document.getElementById("menu_btn");
const navLinks = document.getElementById("nav_links");
const links = document.querySelectorAll("#nav_links a");

menuBtn.addEventListener("click", () => {
    navLinks.classList.toggle("active");

    if (navLinks.classList.contains("active")) {
        menuBtn.textContent = "✕";
        menuBtn.setAttribute("aria-expanded", "true");
    } else {
        menuBtn.textContent = "☰";
        menuBtn.setAttribute("aria-expanded", "false");
    }
});

links.forEach((link) => {
    link.addEventListener("click", () => {
        navLinks.classList.remove("active");
        menuBtn.textContent = "☰";
        menuBtn.setAttribute("aria-expanded", "false");
    });
});

Cómo probar el navbar responsive

Para comprobar que todo funciona, abre el proyecto en el navegador.

En pantalla grande deberías ver el logo a la izquierda y los enlaces a la derecha.

Luego reduce el ancho del navegador. Cuando llegue al tamaño configurado en la media query, los enlaces se ocultarán y aparecerá el botón de hamburguesa.

Al hacer clic en el botón, el menú se desplegará con animación. El icono cambiará a una X y los enlaces aparecerán uno por uno.

Si haces clic en un enlace, el menú se cerrará automáticamente.

Resumen del proceso

  • Crear la estructura HTML con header, nav, logo, botón y enlaces.
  • Aplicar estilos básicos con CSS.
  • Organizar el navbar con Flexbox.
  • Ocultar el botón hamburguesa en pantallas grandes.
  • Usar una media query para pantallas pequeñas.
  • Crear el menú desplegable con clip-path.
  • Agregar animación a los enlaces.
  • Usar JavaScript para abrir y cerrar el menú.
  • Cambiar el icono del botón según el estado.
  • Cerrar el menú al hacer clic en un enlace.

Conclusión

Crear un navbar responsive con HTML, CSS y JavaScript es una práctica muy útil para cualquier proyecto web.

Con HTML construimos la estructura, con CSS damos estilo, adaptamos el diseño a móviles y agregamos animaciones. Finalmente, con JavaScript controlamos la apertura, el cierre y el cambio de icono del menú.

Este tipo de menú es ideal para portafolios, páginas personales, sitios de servicios, landing pages y cualquier sitio web que necesite una navegación moderna y adaptable.

Compartir
Escrito por
deybi
Soy un joven dominicano dedicado a la creación de páginas web, con un proyecto de vida claro y una visión enfocada en el crecimiento, la disciplina y el trabajo constante. Me esfuerzo cada día...

Deja un comentario