Diseñando un menú responsive con HTML5, CSS3 y jQuery.

5
60313

Cómo adaptar el menú de nuestra página web a un diseño responsive

Índice de contenidos

1. Entorno

El tutorial está escrito usando el siguiente entorno:

  • Hardware: Portátil MacBook Pro 15 pulgadas (2.4 GHz Intel i7, 8GB 1333 Mhz DDR3, 500GB Flash Storage).
  • Sistema Operativo: Mac OS X Mavericks 10.9.5
  • Sublime text 2.0.2
  • jQuery 2.1.3
  • Normalize.css v3.0.2

2. Introducción

En los tiempos actuales, el diseño de las páginas web tiene que ser responsive para que pueda ser navegable desde cualquier tipo de dispositivo. El diseño responsive implica que las dimensiones y distribución de los elementos en la página varíen en función de las dimensiones de la pantalla que está mostrando el contenido.

Aunque ya disponemos de una gran cantidad de librerías que nos permiten dar un diseño responsive a nuestras web, como Bootstrap, a veces perdemos transparencia y no somos conscientes de qué aspectos hay que tener en cuenta para hacer un diseño lo más flexible posible.

En este tutorial aprenderemos cómo diseñar el menú de una página web responsive a través de CSS3 y JavaScript, de modo que en pantallas grandes se muestre de manera tradicional, opciones de menú alineadas en una cabecera, y para pequeños dispositivos quede oculto y mostrarse sólo al hacer click sobre un elemento concreto de la página.

3. Instalando las herramientas

Para el desarrollo de este tutorial, se han utilizado las herramientas normalize.css y jQuery. Para instalar las últimas versiones podemos acceder a los sitios web de jquery y normalize.css y descargar directamente los fuentes o instalarlos a través de npm:

  • Para jquery: npm install jquery
  • Para normalize.css: npm install normalize.css

En nuestro tutorial, hemos instalado estas dependencias a través de npm, por lo que las rutas son relativas al directorio node-modules.

4. Diseño inicial de nuestro menú

Vamos a diseñar una web muy sencilla que constará de lo siguiente:

  • Una cabecera con un logo en la parte izquierda y un menú en la parte derecha
  • El menú constará de las opciones Archivo, Sobre mí y Contacto
  • El body de nuestra página será un parráfo con texto

Utilizaremos HTML5 para la maquetación de la página index.html, quedando como sigue:

    <!DOCTYPE html>
    <html lang="en">
    <head>
      <meta charset="UTF-8">
      <title>Mi web</title>
      <meta name="viewport" content="width=device-width, initial-scale=1" />
      <link rel="stylesheet" href="node_modules/normalize.css/normalize.css" >
    </head>
    <body>
      <header class="page-header">
        <div class="center-contents">
          <a class="logo" href="#" title=""><img src="images/logo-example.png" alt=""></a>
          <nav class="page-nav">
            <ul>
              <li><a href="#" title="">Archive</a></li>
              <li><a href="#" title="">About us</a></li>
              <li><a href="#" title="">Contact</a></li>
            </ul>
          </nav>
        </div>
      </header>

      <main class="page-contents">
        <h1>Titular de la página</h1>
        <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Quia recusandae ipsa beatae consequuntur. Dolor repudiandae fugiat, rem, adipisci sit tenetur dolores corrupti amet molestiae, consequatur labore. Laboriosam sit voluptate quaerat!</p>
        <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Quia recusandae ipsa beatae consequuntur. Dolor repudiandae fugiat, rem, adipisci sit tenetur dolores corrupti amet molestiae, consequatur labore. Laboriosam sit voluptate quaerat!</p>
      </main>
    </body>
    </html>
  

Añadimos los estilos en un fichero aparte styles.css en el directorio raíz:

Ubicacion del directorio

El contenido de la hoja de estilos es el siguiente:

     /************************
        HEADER
      ************************/

      .page-header{
        overflow: hidden;
        background: #444;
        padding: 1em 0 0 ;
      }

      .page-header .center-contents{
        max-width: 650px;
        margin:auto;
        overflow: hidden;
      }

      .logo{
        max-width: 60px;
        display: block;
        float: left;
        margin: 0 0 1em 1em;
      }

      .logo img{
        display: block;
      }

      .page-nav{
        color: #fff;
        float:right;
      }

      .page-nav ul, .page-nav li{
        list-style:none;
        margin:0;
        padding: 0;
        float: left;
      }

      .page-nav a{
        color: #fff;
        width: 100%;
        height: auto;
        display: block;
        padding: 0.75em 1em;
        text-decoration: none;
        cursor: pointer;
      }


      /************************
        MAIN CONTENTS
      ************************/

      .page-contents{
        padding:0 1em;
        max-width: 650px;
        margin:auto;
      }
  

La apariencia de nuestro menú inicial es la siguiente:

Menu inicial

5. Mostrando/ocultando el menú en la vista responsive

Aunque el diseño de nuestra página es responsive, el diseño del menú no es el más adecuado para dispositivos pequeños. Al igual que hacen librerías como Bootstrap, vamos a hacer que cuando el tamaño sea reducido el menú se comprima y sólo al seleccionarlo se despliegue y nos muestre las opciones.

Partiremos de un diseño inicial para resoluciones pequeñas en el que aparece nuestro menú oculto y una etiqueta que flote a la derecha de nuestra cabecera y a la que daremos comportamiento para que al hacer click sobre ella desplegue/oculte el menu:

    <!DOCTYPE html>
    <html lang="en">
    <head>
      <meta charset="UTF-8">
      <title>Mi web</title>
      <meta name="viewport" content="width=device-width, initial-scale=1" />
      <link rel="stylesheet" href="node_modules/normalize.css/normalize.css" >
    </head>
    <body>
      <header class="page-header">
        <div class="center-contents">
          <div;>
            <a class="logo" href="#" title=""><img src="images/logo-example.png" alt=""></a>
            <span class="toggle-nav">Menu</span>
          </div;>
          
          <nav class="page-nav collapse">
            <ul>
              <li><a href="#" title="">Archive</a></li>
              <li><a href="#" title="">About us</a></li>
              <li><a href="#" title="">Contact</a></li>
            </ul>
          </nav>
        </div>
      </header>

      <main class="page-contents">
        <h1>Titular de la página</h1>
        <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Quia recusandae ipsa beatae consequuntur. Dolor repudiandae fugiat, rem, adipisci sit tenetur dolores corrupti amet molestiae, consequatur labore. Laboriosam sit voluptate quaerat!</p>
        <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Quia recusandae ipsa beatae consequuntur. Dolor repudiandae fugiat, rem, adipisci sit tenetur dolores corrupti amet molestiae, consequatur labore. Laboriosam sit voluptate quaerat!</p>
      </main>
      <script type="text/javascript" src="node_modules/jquery/dist/jquery.min.js"></script>

    </body>
    </html>
  

Y las clases CSS que consiguen este efecto son las siguientes:

    .page-header{
      overflow: hidden;
      background: #444;
      padding: 1em 0 0 ;
      height: 4em;

      transition:all .4s linear;
    }

    .page-nav{
      color: #fff;
      clear:left;
      position: relative;
      visibility: inherit;
      transition:visibility .4s linear;
    }

    .page-nav a{
      color: #fff;
      width: 100%;
      height: auto;
      display: block;
      padding: 0.75em 1em;
      text-decoration: none;
      border-top:#666 1px solid;
      cursor: pointer;

    }
     
    .toggle-nav {
      float: right;
      padding: 1em;
      margin: 0 0 1em 1em;
      color: rgb(255,255,255);
      cursor: pointer;
    }

    .page-nav.collapse {
      visibility: hidden;

    }

    .menu-expanded {
      height: 11em;
    }
  

Como vemos, el menú se oculta a través de la propiedad de CSS3 de visibility. Para conseguir un efecto de que el menú se expande y contrae al mostrarse, hemos añadido transiciones en el height del header y en visibility del nav.

Ahora debemos añadir un manejador del evento de click sobre la etiqueta de menú para añadir/quitar las clases que muestran/ocultan el menú. Para ello, utilizaremos jQuery. Creamos en nuestro directorio raíz un fichero application.js y lo referenciamos inmediatamente después de la librería de jquery en nuestro index.html:

    <!DOCTYPE html>
    <html lang="en">
    <head>
      <meta charset="UTF-8">
      <title>Mi web</title>
      <meta name="viewport" content="width=device-width, initial-scale=1" />
      <link rel="stylesheet" href="node_modules/normalize.css/normalize.css" >
    </head>
    <body>
      ...

      <main class="page-contents">
        ...
      </main>
      <script type="text/javascript" src="node_modules/jquery/dist/jquery.min.js"></script>
      <script type="text/javascript" src="application.js"></script>
      
    </body>
    </html>
  

El script deberá controlar el evento de click y al capturarlo hacer un toggle de las clases .collapse y .menu-expanded en la etiqueta y header respectivamente. Los selectores de elementos siempre serán a través de clases CSS y no de identificadores:

    function toggleNavigation(){
      $('.page-header').toggleClass('menu-expanded');
      $('.page-nav').toggleClass('collapse');
    }

    // EVENTOS DEL DOM
    $(window).on('load',function(){
      $('.toggle-nav').click(toggleNavigation);
    });
  

La apariencia de nuestro menú oculto:

Menu oculto

Al desplegarlo:

Menu desplegado

6. Media queries: haciendo nuestro menú responsive

Una vez ya tenemos los dos diseños de menú, a través de media queries, podemos aplicar unas clases u otras a nuestros componentes para así ver el menú con el primer diseño para pantallas grandes (anchura mínima de 700px) y el oculto para pequeñas (mínima de 450px) :

    /************************
      HEADER
    ************************/

    .page-header{
      overflow: hidden;
      background: #444;
      padding: 1em 0 0 ;
      height: 4em;

      transition:all .4s linear;
    }

    .page-header .center-contents{
      max-width: 650px;
      margin:auto;
      overflow: hidden;
    }

    .logo{
      max-width: 60px;
      display: block;
      float: left;
      margin: 0 0 1em 1em;
    }

    .logo img{
      display: block;
    }

    .page-nav{
      color: #fff;
      /*position: relative;
      visibility: inherit;
      transition:visibility .4s linear;*/
    }

    .page-nav ul, .page-nav li{
      list-style:none;
      margin:0;
      padding: 0;
    }

    .page-nav a{
      color: #fff;
      width: 100%;
      height: auto;
      display: block;
      padding: 0.75em 1em;
      text-decoration: none;
      border-top:#666 1px solid;
      cursor: pointer;

    }
     
    .toggle-nav {
      float: right;
      padding: 1em;
      margin: 0 0 1em 1em;
      color: rgb(255,255,255);
      cursor: pointer;
    }


    .menu-expanded {
      height: 11em;
    }


    /************************
      MAIN CONTENTS
    ************************/

    .page-contents{
      padding:0 1em;
      max-width: 650px;
      margin:auto;
    }


    /************************
      MEDIA QUERIES
    ************************/
    @media only screen and (min-width:450px){
      .page-header span{
        display: block;
      }
      
      .page-nav {
        clear:left;
        position: relative;
        visibility: inherit;
        transition:visibility .4s linear;
      }

    }

    @media only screen and (min-width:700px){
      .page-header{
        height: 4em;
      }
      .logo{
        max-width: 92px;
      }
      .page-nav{
        width: auto;
        float: right;
        display: block;
        clear: none;
        visibility: visible;
      }
      .page-header span{
        display: none;
      }

      .page-nav ul, .page-nav li{
        float: left;
      }

      .page-nav a {
        border-top: none;
      }

    }

    @media only screen and (max-width:699px){
      .collapse {
        visibility: hidden;
      }
    }

    @media only screen and (min-width:700px){
      .collapse {
        visibility: inherit;
      }
    }
  

Si cambiamos la resolución de nuestro navegador, vemos cómo la vista del menú cambia.

7. Conclusiones

Ya hemos visto cómo con CSS3 y jQuery podemos hacer un diseño responsive de nuestra web. Gracias a los nuevos recursos como transformaciones y media queries con muy poco código conseguimos un diseño adaptado y sin uso de librerías que pueden afectar al rendimiento de nuestra web.

El tutorial completo podéis verlo en mi repositorio de GitHub

5 COMENTARIOS

  1. muy bueno el ejemplo, lo puse en practica pero agragando mas item al menu y todo bien pero al verlo en pantalla chica nada mas muestra 3 item originales no expande mas, que ay que hacer

  2. Buenas noches.
    Excelente la explicación, realizada con cuidado y detalle.
    Tengo un pequeño problema: al hacer click sobre «menú» no abre el menú vertical. ¿Qué debo revisar?
    Muchas gracias.

    Carlos

      • Hola Carlos,

        Si estás incorporando a una web que tenga sus propios estilos, es posible que para los elementos li se esté aplicando alguno que tengas definido y por tanto se muestren en horizontal. Prueba a incluir en los elementos del menú la propiedad display para que se muestren como quieres.

        Saludos,
        Sara

DEJA UNA RESPUESTA

Por favor ingrese su comentario!

He leído y acepto la política de privacidad

Por favor ingrese su nombre aquí

Información básica acerca de la protección de datos

  • Responsable:
  • Finalidad:
  • Legitimación:
  • Destinatarios:
  • Derechos:
  • Más información: Puedes ampliar información acerca de la protección de datos en el siguiente enlace:política de privacidad