Conceptos de menú receptivo | Programar Plus

La siguiente es una publicación invitada de Tim Pietrusky. Conozco a Tim por su prolífico trabajo en CodePen y por ser un miembro útil de la comunidad allí. Me escribió con esta publicación de invitado sobre menús receptivos que estoy más que feliz de compartir con ustedes a continuación. No solo es un concepto oportuno, sino que uno de los conceptos mejora un ingenioso truco de CSS que hemos cubierto aquí en el pasado.

Cuando se trata de diseño receptivo, nos enfrentamos a varias técnicas sobre cómo manejar mejor la alteración de nuestros menús de navegación para pantallas pequeñas. Los recursos parecen infinitos. Es por eso que les mostraré cuatro conceptos principales y discutiré las ventajas y desventajas de todos ellos.

Tres de ellos están hechos con CSS puro y uno usa una sola línea de JavaScript.

Antes que empecemos

En el código presentado en este artículo, no utilizo ningún prefijo de proveedor para que el CSS sea más fácil de ver y comprender. Los ejemplos de CSS más complejos usan SCSS. Cada ejemplo está alojado en CodePen, donde puede ver el CSS compilado si lo desea.

Todos los conceptos de menú de este artículo se basan en esta estructura HTML simple a la que llamo menú básico. El atributo de función se utiliza para especificar el concepto en particular (horizontal completo, selección, menú desplegable personalizado y fuera del lienzo).

<nav role="">
  <ul>
    <li><a href="https://css-tricks.com/responsive-menu-concepts/#">Stream</a></li>
    <li><a href="https://css-tricks.com/responsive-menu-concepts/#">Lab</a></li>
    <li><a href="https://css-tricks.com/responsive-menu-concepts/#">Projects</a></li>
    <li><a href="https://css-tricks.com/responsive-menu-concepts/#">About</a></li>
    <li><a href="https://css-tricks.com/responsive-menu-concepts/#">Contact</a></li>
  </ul>
</nav>​

Para abordar las pantallas pequeñas, utilizo la misma consulta de medios en todos los conceptos.

@media screen and (max-width: 44em) {

}

1. Horizontal completo

Este es el enfoque más simple porque solo necesita hacer que los elementos de la lista sean de ancho completo en pantallas pequeñas.

<nav role="full-horizontal">
  <ul>
    <li><a href="https://css-tricks.com/responsive-menu-concepts/#">Stream</a></li>
    <li><a href="https://css-tricks.com/responsive-menu-concepts/#">Lab</a></li>
    <li><a href="https://css-tricks.com/responsive-menu-concepts/#">Projects</a></li>
    <li><a href="https://css-tricks.com/responsive-menu-concepts/#">About</a></li>
    <li><a href="https://css-tricks.com/responsive-menu-concepts/#">Contact</a></li>
  </ul>
</nav>​
@media screen and (max-width: 44em) {
  nav[role="full-horizontal"] {
    ul > li {
      width: 100%;
    }
  }
}

Así es como se ve en una pantalla pequeña con un estilo personalizado.

full-horz

Ventajas

  • Sin JavaScript
  • Sin HTML adicional
  • CSS simple

Desventajas

  • Reserva demasiado espacio en la pantalla

Manifestación

En CodePen:

2. Seleccione

Este concepto oculta el menú básico en pantallas pequeñas y muestra un menú de selección en su lugar.

Para lograr esto, necesitamos extender nuestro marcado básico y agregar una selección. Para que la selección funcione, también agregamos algo de JavaScript que altera window.location.href cuando ocurre el evento onchange en la selección.

<nav role="select">
  <!-- basic menu goes here -->
  
  <select onchange="if (this.value) window.location.href = this.value;">
    <option value="https://css-tricks.com/responsive-menu-concepts/#">Stream</option>
    <option value="https://css-tricks.com/responsive-menu-concepts/#">Lab</option>
    <option value="https://css-tricks.com/responsive-menu-concepts/#">Projects</option>
    <option value="https://css-tricks.com/responsive-menu-concepts/#">About</option>
    <option value="https://css-tricks.com/responsive-menu-concepts/#">Contact</option>
  </select>
</nav>​

Ocultamos la selección en pantallas grandes.

nav[role="select"] {
  > select {
    display:none;  
  }
}

En pantallas pequeñas, ocultamos el menú básico y mostramos la selección. Para ayudar al usuario a reconocer que se trata de un menú, también estamos agregando un pseudoelemento con el texto “Menú”.

@media screen and (max-width: 44em) {
  nav[role="select"] {
    ul {
      display: none;
    }

    select {
      display: block;
      width: 100%;
    }

    &:after {
      position: absolute;
      content: "Menu";
      right: 0;
      bottom: -1em;
    }
  }
}

Así es como se ve en una pantalla pequeña con un estilo personalizado.

num-2

Ventajas

  • No necesita mucho espacio
  • Utiliza controles nativos

Desventajas

  • Necesita JavaScript
  • Contenido duplicado
  • Seleccionar no tiene estilo en todos los navegadores

Manifestación

En CodePen:

3. Menú desplegable personalizado

Este concepto oculta el menú básico en pantallas pequeñas y muestra una entrada y una etiqueta (para usar Checkbox Hack) en su lugar. Cuando el usuario hace clic en la etiqueta, el menú básico se muestra debajo.

<nav role="custom-dropdown">
    <!-- Advanced Checkbox Hack (see description below) -->
    
    <!-- basic menu goes here -->
</nav>​

Problema con el truco de casilla de verificación

Hay dos problemas con el truco de casilla de verificación predeterminado:

  1. No funciona en Safari móvil (iOS No es posible hacer clic en la etiqueta en la solución iOS es agregar un clic vacío en la etiqueta.
  2. No funciona en el navegador de Android predeterminado (Android Érase una vez un WebKit Adyacente / General Sibling & Pseudo Class Bug que impedía el uso de pseudoclases combinadas con combinadores de hermanos adyacentes (+) o generales (~).
h1 ~ p { color: black; }
h1:hover ~ p { color: red; }

Esto no tiene ningún efecto porque el truco de la casilla de verificación utiliza la pseudo-clase: comprobado combinado con el hermano general. Y dado que esto se solucionó en WebKit 535.1 (Chrome 13) y el WebKit real en Android 4.1.2 es 534.30, el truco de casilla de verificación normal no funciona en ningún dispositivo Android hasta la fecha.

La mejor solución es agregar una animación falsa solo de WebKit en el elemento del cuerpo.

Todas las cosas combinadas crean el Hack avanzado de casilla de verificación:

<!-- Fix for iOS -->
<input type="checkbox" id="menu">
<label for="menu" onclick></label>
/* Fix for Android */
body { 
  -webkit-animation: bugfix infinite 1s; 
}
@-webkit-keyframes bugfix { 
  from { padding: 0; } 
  to { padding: 0; } 
}

/* default checkbox */
input[type=checkbox] {
  position: absolute;
  top: -9999px;
  left: -9999px;
}

label { 
  cursor: pointer;
  user-select: none;
}

Referencia: Hack avanzado de casilla de verificación

Para pantallas grandes, ocultamos la etiqueta:

nav[role="custom-dropdown"] {
  label {
    display: none;
  }
}

Para pantallas pequeñas, ocultamos el menú básico y mostramos la etiqueta. Para ayudar al usuario a reconocer que este es un menú, también estamos agregando un pseudo-elemento con el texto “≡” (convertido a ” 2261″ para usarlo como contenido en el pseudo-elemento) a la etiqueta. Cuando el usuario hace clic en la entrada, se muestra el menú básico y los elementos de la lista se expanden al ancho completo.

@media screen and (max-width: 44em) {
  nav[role="custom-dropdown"] {
    ul {
      display: none;
      height: 100%;
    }

    label {
      position: relative;
      display: block;
      width: 100%;
    }

    label:after {
        position: absolute;
        content: "2261";
    }
    
    input:checked ~ ul {
      display: block;
    
      > li {
        width: 100%;
      }        
    }
  }
}

Así es como se ve el menú en una pantalla pequeña con un estilo personalizado.

cerradoCerrado
abiertoAbierto

Ventajas

  • No necesita mucho espacio cuando está cerrado
  • Estilo personalizado
  • Sin JavaScript

Desventajas

  • Semántica incorrecta (entrada / etiqueta)
  • HTML adicional

Manifestación

En CodePen:

4. Fuera del lienzo

Este concepto oculta el menú básico en pantallas pequeñas y muestra una entrada HTML y una etiqueta (para usar el truco de casilla de verificación avanzada, consulte 3. Menú desplegable personalizado para obtener más información). Cuando el usuario hace clic en la etiqueta, el menú básico vuela desde la izquierda y el contenido se mueve hacia la derecha; la pantalla se divide: menú ~ 80% y contenido ~ 20% (depende de la resolución y las unidades css).

<input type="checkbox" id="menu">
<label for="menu" onclick></label>

<!-- basic menu goes here -->

<div class="content">
  <!-- content goes here -->
</div>

En pantallas grandes, ocultamos la etiqueta.

label {
  position: absolute;
  left: 0;
  display: none;
}

En pantallas pequeñas, ocultamos el menú básico fuera de la ventana gráfica y mostramos la etiqueta / entrada. Para ocultar el menú, especificamos un ancho ($ menu_width) y le agregamos una posición negativa. Para ayudar al usuario a reconocer que este es un menú, también estamos agregando un pseudo-elemento con el texto “≡” (convertido a ” 2261″ para usarlo como contenido en el pseudo-elemento) a la etiqueta.
Cuando el usuario hace clic en la entrada, el menú básico vuela desde la izquierda y el contenido se mueve hacia la derecha.

@media screen and (max-width: 44em) {
  $menu_width: 20em;

  body {
    overflow-x: hidden;
  }
    
  nav[role="off-canvas"] {
    position: absolute;
    left: -$menu_width;
    width: $menu_width;
    
    ul > li {
      width: 100%;
    }
  }

  label {
    display: block;
  }

  label:after {
    position: absolute;
    content: "2261";
  }

  input:checked ~ nav[role="off-canvas"] {
    left: 0;
  }

  input:checked ~ .content {
    margin-left: $menu_width + .5em;
    margin-right: -($menu_width + .5em);
  }
}​

Así es como se ve el menú en una pantalla pequeña con un estilo personalizado.

offcanvas-cerradoCerrado
offcanvas-openAbierto

Ventajas

  • No necesita mucho espacio cuando está cerrado
  • Estilo personalizado
  • Sin JavaScript
  • Convención de la aplicación Facebook / Google+

Desventajas

  • Semántica incorrecta (entrada / etiqueta)
  • HTML adicional
  • Posición absoluta para el cuerpo = Se siente como una posición fija

Manifestación

En CodePen:

¿Funciona en IE?

Todas las técnicas utilizadas anteriormente tienen un objetivo: ¡Crear menús receptivos para navegadores modernos! Y debido a que no hay IE 8 o inferior en ningún dispositivo móvil, no tenemos que preocuparnos por eso.

(Visited 8 times, 1 visits today)