Menú de hamburguesa fuera del lienzo con CSS puro

, Author

Última actualización el 21 de enero de 2019.

Los menús de hamburguesa fuera del lienzo con CSS puro no son un descubrimiento reciente. Después de todo, Chris Coyier escribió sobre esta técnica en noviembre de 2012.

  • Si este es un viejo truco para ti, entonces aguanta conmigo un poco. He mejorado el ejemplo de Chris, y me encantaría que me dieras tu opinión.
  • Si esto es nuevo para ti, no te preocupes. Tienes mucha compañía, ya que parece que gran parte de la web aún no se ha puesto al día.

Con eso, vamos a construir un menú de hamburguesa fuera del lienzo, simple y responsivo, usando sólo CSS, que será fácil de incorporar a tu propio proyecto. Pero primero…

¿Qué tiene de malo JavaScript?

Nada.

Aaron Gustafson explica la importancia de las Mejoras Progresivas y el papel de JavaScript en el desarrollo web mejor de lo que yo podría. Deberías leer su post. Pero en aras de la brevedad, voy a tratar de resumirlo:

  • «Las tareas principales siempre se pueden realizar sin JavaScript»
  • Las tareas principales deben realizarse en la capa más estable (es decir, no en JavaScript).
  • Las mejoras progresivas no son anti-JavaScript. Se trata simplemente de adoptar las tecnologías correctas en la capa correcta.
  • «Dado que hay alguna posibilidad de que JavaScript no funcione, siempre debemos tener en cuenta esa posibilidad»
  • Nunca es una buena idea ignorar a los usuarios potenciales.
  • Las Mejoras Progresivas son simplemente buena ingeniería.

Así que vamos a hacer todo lo que podamos con HTML y CSS. Luego hacer que JavaScript haga su magia en una capa más apropiada – mejorando la UI ya existente.

Paso 1: HTML

Como ya sabrás, el primer paso es siempre escribir una capa base de HTML sólida y bien pensada.

Nota: Estoy usando Font Awesome para los iconos en mi ejemplo.

Paso 1: HTML inicial para un menú hamburguesa responsivo con CSS puro

Parece bastante estándar, ¿verdad? Tenemos:

  • Nuestro elemento padre <header>
  • El icono de hamburguesa («fa-bars»)
  • Un título principal (o potencialmente un logo)
  • La navegación en un elemento <nav>
  • Un icono de cierre («fa-close») dentro de la navegación (más sobre esto más adelante)
  • Un «fondo» después de la navegación. ¿Por qué es una etiqueta de anclaje? Lo explicaré más adelante.

Paso 2: Hagámoslo más accesible

La accesibilidad nunca debería ser un pensamiento posterior – como después de haber escrito tu aplicación. Debe planificarse desde el principio. ¡Añadir algunas consideraciones básicas ahora no sólo mejorará la accesibilidad general de su sitio, sino que le proporcionará (al desarrollador) un mejor marcado para utilizar en su JavaScript!

Con esto, vamos a añadir unos cuantos atributos más y algo de texto para lectores de pantalla:

Paso 2: Mejorar el HTML para que sea más accesible.

Aquí tienes un rápido desglose de todos estos atributos y cómo funcionan:

  • Hemos añadido IDs únicos para orientar nuestros HREFs (más sobre cómo funciona esto más adelante).
  • Hemos proporcionado una etiqueta informativa de los botones para los lectores de pantalla utilizando .
  • Hemos ocultado los iconos de los lectores de pantalla con , porque son representaciones visuales, y hemos añadido texto sólo para lectores de pantalla con los elementos <span class=»sr-only»>.
  • Hemos eliminado el «telón de fondo» del índice de tabulación con un . Es de naturaleza puramente visual y no queremos confundir a nuestros usuarios con problemas de visión y de teclado.
  • Hemos añadido el atributo amazing para establecer el estado inicial (y semántico) del «telón de fondo». No más basura – ¡qué emocionante!

Aquí está el resultado hasta ahora:

Figura 1: Visualización resultante del HTML después de los pasos 1 y 2.

Paso 3: ¡Pongamos estilo!

Vamos a enfocar esto desde el punto de vista móvil, así que vamos a eliminar la vista móvil, «hamburguesa» (la parte interesante).

Primero, vamos a conseguir que el diseño de la cabecera sea correcto (sin la interactividad):

Paso 3: Añadir algo de CSS para estilizar la cabecera (sin interactividad, por ahora).

El resultado:

Figura 2: Visualización resultante del HTML & CSS después del paso 3.

Paso 4: Interactividad con CSS puro

A la hora de hacer que los widgets sean interactivos con CSS, tienes un par de opciones:

  1. Utilizar radios o casillas de verificación
  2. Utilizar la pseudoclase :target.

Los radios y las casillas de verificación funcionan increíblemente bien para la mayoría de los widgets, como pestañas, modales, desplegables y acordeones. Chris Coyier apodó a esta técnica «el hack de las casillas de verificación». Varios desarrolladores han utilizado este «hack» para sus menús fuera del lienzo, como en el tutorial de Paul Lewis para Chrome Dev Summit o el menú hamburguesa morphing de Luis Manuel.

Sin embargo, la pseudoclase :target es más semántica en este caso de uso, ya que estamos tratando directamente con la navegación. Puede que no estés de acuerdo, ¡y eso está completamente bien! Sería increíblemente fácil y perfectamente aceptable cambiar la pseudoclase :target por una casilla de verificación.

Cualquier técnica tiene sus advertencias, sin embargo.

Usar una casilla de verificación:

  • Requiere que JavaScript cierre el menú fuera del lienzo si uno de los enlaces dentro del menú era un enlace ancla a una sección específica de la misma página.
  • Requiere que el campo <input> sea un hermano del menú o al menos un hermano del ancestro del menú. En otras palabras, el CSS es un poco más complicado. Sin embargo, puede tener la <etiqueta> (incluso varias etiquetas) en otro lugar.
  • El elemento <etiqueta> no será directamente enfocable o tabulable, lo que requiere un CSS un poco más complicado para manejar el foco en la casilla de verificación mientras se cambia la apariencia visible de la <etiqueta>.
  • La navegación con el teclado alrededor de la apertura/cierre del menú será torpe. Afectar a un cambio de estado en una casilla de verificación se hace a través de la no la tecla. Mientras que los usuarios ciegos pueden entender que el widget es operado por una casilla de verificación, los usuarios del teclado con visión se confundirán ya que la casilla de verificación no es evidente – algo que sentí que era una ruptura en este caso de uso.

Usando la pseudo-clase :target:

  • Agrega la apertura/cierre del menú fuera del lienzo al historial del navegador (empujando el hash en la barra de direcciones). Requerirá JavaScript para ejecutar Event.preventDefault() para evitar esto (y el salto potencialmente molesto a la parte superior de la página).

Y puede haber otras advertencias que me perdí. En cualquier caso, la elección de la técnica es una cuestión de preferencia y está sujeta a los requisitos de su proyecto. De todos modos, he divagado…

Aquí está la parte interactiva del CSS:

Paso 4: Añadir algo de CSS para la interactividad.

El resultado al hacer clic:

Figura 3: Visualización resultante del menú hamburguesa cuando se abre.

Cómo funciona todo esto

Esencialmente, la pseudoclase :target nos da un nuevo «estado» para estilizar la navegación dirigida. Cuando el menú principal ha sido apuntado (con su hash añadido a la URL) ahora podemos deslizar el menú. Es un poco como una pseudoclase :focus para el elemento apuntado (no el enlace en sí).

También hemos permitido que el «fondo» se muestre cuando la navegación está apuntada.

Notarás que el icono de la hamburguesa principal está vinculado al ID de la navegación, mientras que tanto el icono de cierre como los botones del fondo están vinculados al icono de la hamburguesa principal. Esto nos permite hacer clic en el icono de cierre o en el telón de fondo para eliminar el «foco» -o realmente :objetivo- de la navegación. Si el telón de fondo no fuera un enlace, no sería clicable sin JavaScript.

También he encadenado los selectores :target junto con el atributo en el CSS. Aquí será donde progresivamente mejoremos el menú hamburguesa con JavaScript para que no salte a la cabecera cuando se haga clic – evitando la advertencia que mencioné antes. Hacer que el JavaScript secuestre el comportamiento hash del navegador significa que la pseudo-clase :target ya no funcionará. Cuando esto ocurra, aprovecharemos el atributo para estilizar la alternancia con valores verdadero/falso de forma muy parecida a como podríamos haberlo hecho en el pasado con las clases.

Mientras tanto, sin embargo, esto funciona maravillosamente sin JavaScript.

He añadido la consulta de medios @supports para proporcionar el CSS preferido position:fixed a los navegadores (tanto móviles como de escritorio) que lo soportan. De lo contrario, los navegadores y dispositivos cojos -te miro a ti, iOS- obtendrán position:absolute.

Paso 5: Estilos para pantallas más grandes

Como no queremos que el menú hamburguesa se muestre en dispositivos no móviles (o en pantallas más grandes en general), añadiremos la media query necesaria para ello. Luego le daremos estilo para que parezca una navegación horizontal:

Paso 5: CSS para estilizar la navegación en pantallas más grandes.

El resultado:

Figura 4: Visualización resultante de la navegación estilizada para pantallas más grandes.

¡Voilà! Hemos terminado!

Poniéndolo todo

Aquí está el HTML final:

El HTML final para el menú hamburguesa responsivo usando sólo CSS.

Aquí está el CSS final:

CSS final para el menú hamburguesa responsivo.

Demo

Prueba mi CodePen por ti mismo:
→ Menú hamburguesa CSS puro sin JavaScript.

Nota: puedes hacer una demostración de la versión del menú con casillas de verificación también.

¿Quieres añadir JavaScript para hacerlo más hábil?

Aunque podemos hacer que el menú fuera del lienzo funcione completamente con CSS -mejorando su rendimiento y fiabilidad- seguiremos necesitando que JavaScript nos ayude de alguna manera para mejorar la interactividad que rodea a los inconvenientes de cualquiera de las dos técnicas. También se puede utilizar JavaScript para evitar el desplazamiento en la página mientras el menú está abierto.

También vale la pena señalar que se puede lograr un nivel decente (y posiblemente el más importante) de accesibilidad sin JavaScript. Sin embargo, es difícil proporcionar un nivel sólido de accesibilidad sin la capacidad de JavaScript para manipular el DOM (por ejemplo, la gestión del enfoque, las actualizaciones de atributos ARIA, etc.).

Para obtener más información sobre la mejora de la accesibilidad de su sitio web a través de JavaScript, consulte los siguientes artículos:

  • Usando atributos ARIA para la configuración del estado de JavaScript & estilo
  • Escribiendo JavaScript con la accesibilidad en mente

¿Tiene otras ideas o sugerencias?

Me encantaría escuchar sus comentarios con mi enfoque de un menú de hamburguesa CSS puro.

Editos y cavilaciones posteriores

21 de enero de 2019: Artículo editado y ejemplos de código actualizados para eliminar atributos ARIA innecesarios y mejorar la accesibilidad.

A medida que he aprendido más sobre el uso de ARIA y el desarrollo de &pruebas de accesibilidad en general, me he dado cuenta de algunas cosas:

  1. JavaScript definitivamente tiene su lugar, y debe ser parte de cualquier patrón de interfaz de usuario de accesibilidad robusta.
  2. A excepción de los puntos de referencia ARIA, JavaScript es necesario para utilizar ARIA correctamente. Y, muchos de los atributos que he utilizado, como es mejor dejar para JavaScript para agregar una vez cargado en lugar de añadir directamente en el marcado. Este concepto sigue las buenas prácticas de Mejora Progresiva-los estados y propiedades de ARIA junto con JavaScript son una actualización y deben ser manejados en una capa separada.
  3. Antes, no manejaba el foco correctamente ya que el foco desaparecía a medida que avanzaba por los enlaces visualmente ocultos (cuando se colapsaban). He añadido un display: none; al CSS del menú para arreglar esto.

Así que, si has implementado una versión anterior de mi menú de hamburguesa fuera del lienzo con CSS puro, ¡considera la posibilidad de actualizarlo a esta versión más sencilla y accesible!

Deja una respuesta

Tu dirección de correo electrónico no será publicada.