Crea tu web, tutor html, css
 

Barra de navegacion responsive

Una barra de navegación horizontal que se transforma en un menu desplegable cuando el tamaño de la pantalla es demasiado pequeño para mostrar todas las opciones de navegación.

Para lograr este objetivo necesitamos:

  • Estilos CSS
  • Javascript

En cuando al CSS vamos a usar el modelo flexbox para situar los elementos del menu, el botón de desplegar y un logo

Antes de seguir veamos el esquema de funcionamiento para que entiendas como se construye y puedas modificarla si quieres personalizarla.

Barra de menu responsive
La barra de menu para pantallas anchas
Barra de menu responsive
La barra de menu para pantallas pequeña

El esquema lo conoces seguramente porque actualmente casi cualquier página usa este esquema: al ver la pa´gina en una pantalla pequeña el menu horizontal desaparece y aparece un botón, al pulsarlo el menu vuelve a aparecer pero en vertical.

Vamos a usar flexbox para implementar este menú. En la imagen tienes el esquema apra que no te pierdas. Los items del menú los vamos a poner usando una lista desorndenada (ul), pero podrían usarse bloques div.

La página HTML

La cajaNav es un contenedor que englobará dos bloques:

  • titNav: contiene un Logo y el botón de abrir cerrar el menu
  • barNav: la barra del menú con las opciones

El primer bloque contiene el logo (en este ejempo la plabra LOGO) y un botón, en este ejemplo con la palabra Menu, puedes usar el ya habitual icono de tres lineas horizontales (burguer button). Este botón está oculto en pantalla grande y se muestra en pantalla pqueña.

La barra de menú es una lista desordenada con enlaces a otras páginas. En pantalla grande se muestra en horizontal en la parte superior. En pantallas pequeñas estará oculto y al pulsar el botón de menu se abrirá en vertical. Lo he puesto en el lateral derecho de la pantalla, es decir, bajo el botón. Pero puedes dejarlo centrado.

La cajaNav es un flexbox en horizontal (rows) para pantallas anchas y en vertical (columns) para pantallas estrechas. Para que logo y menu quedan en los extremos de la caja este flexbox usa justify-content: space-between

<nav class="cajaNav">
<div class="titNav">
<div class="logo">LOGO</div>
<div class="toggle" onclick="alternar('menu')">Abrir</div>
</div>
<ul class="barNav cerrado" id="menu">
<li><a href="#">item 1</a></li>
<li><a href="#">item 2</a></li>
<li><a href="#">item 3</a></li>
<li><a href="#">item 4</a></li>
</ul>
</nav>

No olvides poner en la sección head de tu página el meta que permite a la página adaptarse a la pantalla con que se está viendo:

<meta name="viewport" content="initial-scale = 1.0, maximum-scale = 1.0, user-scalable = yes, width = device-width">

Los estilos CSS

Si miras ahora mismo la página no verás nada parecido a una barra superior con opciones de menú, ni responsive. El aspecto visual se lo vamos a dar ahora con los estilos CSS.

La cajaNav es un flexbox en horizontal (rows) para pantallas anchas y en vertical (columns) para pantallas estrechas. Para que elos items hijjos, titNav y barNav queden en los extremos de la caja este flexbox usa justify-content: space-between

El bloque titNav es otro flexbox, horizontal (rows) con el botón oculto en pantalla grande y visible en pequeñas. La propiedad justify-content la ponemos en space-between para que ambos queden en extremos opuestos. En pantalla pequeña este bloque se pondrá al ancho completo.

El bloque barNav es la barra de menú, estilo flexbox en horizontal para pantallas anchas y en vertical para pantallas pequeñas. En estas últimas estará oculto y al pulsar el botón de menu se abrirá en vertical. Lo he puesto en el lateral derecho de la pantalla, es decir, bajo el botón. Pero puedes dejarlo centrado.

El resto son detalles como colores de fondo, hover, tipos de letra,... lo habitual para redondear el aspecto visual.

Para diferencias entre pantalla ancha y pequeña se usa un media query, he puesto @media (max-width: 576px). Es decir los cambios se producirán tomando como pantalla grande la que tengana más de 576px de ancho. Puedes colocar otro tamaño o agregar otros puntos para considerar otros tamaños. Para este ejemplo es suficiente.

@charset "utf-8";
/* CSS Document */
:root{
--color:white;
--fnd : #1b0202;
--fndRsp: white;
--colorRsp: black;
}
.cajaNav{
font-family: sans-serif;
display:flex;
justify-content: space-between;
background:var(--fnd);
color: var(--color);
}
.cajaNav .barNav{
margin:0 10px 0 0;
}
.cajaNav .titNav{
display:flex;
justify-content:space-between;
align-items:center;
flex: 1;
background:var(--fnd);
color:var(--color);
height:auto;
}
.cajaNav .titNav .toggle{
display:none;
}
.cajaNav .titNav .logo{
margin: 10px 10px; }
.cajaNav .barNav {
display:flex;
list-style:none;
align-items: center;
padding:0;
}
.cajaNav .barNav li{
display:flex;
align-items:center;
padding: 0 20px ;
height:100%;
}
.cajaNav .barNav li:hover{
background: var(--color);
color:var(--fnd);
cursor: pointer;
}
.cajaNav .barNav li a{
text-decoration: none;
cursor: pointer;
color:inherit;
}
Estilos CSS, para pantalla grande

Al inicio del archivo css hemos puesto unas variables para facilitar el trabajo si quieries personalizar colores.

Al bloque barNav, la barra de menu, le ajustamos los márgenes para que quede a la altura con el bloque del logo. Al ser una lista <ul> el navegador le da unos márgenes por defecto para indentar los items, aquí los personalizamos.

El botón se oculta con la clase .toggle. Si vas a usar un icono con este botón recuerda insertar el archivo CSS del conjunto de iconos.

Los items son elmentos <li>, los ponemos en formato flex para facilitar el centrado vertical del texto que incluyan. La altura se fija para que cubra todo el alto de la barra. También se formate el link (<a>) y el efecto hover para el cursor.

Y ahora la parte responsive. Se ha definido un solo límite, 576px. Por debajo de este ancho entran a funcionar estas definiciones CSS. Las definiciones anteriores de CSS siguen activas, pero pueden ser sobreescritas por las que se definen en este bloque.

No olvides poner en la sección head de tu página el meta que permite a la página adaptarse a la pantalla con que se está viendo:

<meta name="viewport" content="initial-scale = 1.0, maximum-scale = 1.0, user-scalable = yes, width = device-width">

@media (max-width: 576px){
.cajaNav{
flex-direction: column;
align-items:flex-end;
background: unset;
}
.cajaNav .barNav{
color:black;
background:white;
flex-direction:column;
display:none;
}
.cajaNav .barNav li {
padding: 10px 20px;
}
.cajaNav .barNav li:hover{
background: var(--fnd);
color: var(--color);
}
.cajaNav .titNav{
width: 100%;
align-items:center;
}
.cajaNav .titNav .toggle{
display:block;
margin-right:10px;
cursor:pointer
}
.abierto{display:flex !important}
.cerrado{display:none !important}
}
La meta regla CSS query selection para ventanas estrechas

Observa el cambio de dirección de los flexbox.

La caja cajaNav pasa a ser una columna. La primera fila de la columna será la barra del logo y el botón, que ahora pasa a estar visible (display:block). Ahora esta barra debe terner el ancho de su contenedor.

Los elementos del menu, los bloques <li> ahora necesitan un padding vertical, para evitar que queden demasiado juntos.

Si tienes la hoja de estilo puede probar a ver la página en pantalla ancha y estrecha. Si en la pantalla estrecha quieres ver la barra de menus desplegada pon la propipedad display de .barNav en display:flex.

Las dos últimas reglas son importantes por que son las que nos permiten abrir o cerrar el menu. El atributo !important aplicada a display le da prioridad sobre otros valores con las que pueda coincidir.

El Javascript

Hace falta un poquito de Javascript para abrir y cerrar el menú. Es una función muy simple que se activa aplicando un evento click al botón toggle.

Se ha asignado el evento por el métdo clásico, en el propio HTML se usa onclick="alternar(menu)". Llama a la función alternar() para que se aplique al bloque con id menu.

<script>
function alternar(menu)
{
var oMenu = document.getElementById(menu);
//Si el menu tiene clase abierto
//cambia clase a cerrado y cambia el botón
if (oMenu.classList.contains('abierto')){
oMenu.classList.remove('abierto');
oMenu.classList.add('cerrado');
event.target.innerText = 'Abrir'
}
//Si no está abierto, cambia clase a abierto y cambia el botón
else{
oMenu.classList.remove('cerrado');
oMenu.classList.add('abierto');
event.target.innerText = 'Cerrar'
}
}
</script>