Menu hamburger off-canvas réactif et purement CSS

, Author

Dernière mise à jour le 21 janvier 2019.

Les menus hamburger off-canvas purement CSS ne sont pas une découverte récente. Après tout, Chris Coyier a écrit sur cette technique en novembre 2012.

  • Si c’est un vieux truc pour vous, alors restez avec moi un peu. J’ai amélioré l’exemple de Chris, et j’aimerais avoir votre avis.
  • Si c’est nouveau pour vous, ne vous inquiétez pas. Vous avez beaucoup de compagnie, car il semble qu’une grande partie du web n’a pas encore réellement pris le dessus.

Avec cela, nous allons construire un menu hamburger off-canvas simple et réactif en utilisant seulement CSS qui sera facile à incorporer dans votre propre projet. Mais d’abord…

Qu’est-ce qui ne va pas avec JavaScript ?

Rien.

Aaron Gustafson explique l’importance des améliorations progressives et le rôle de JavaScript dans le développement web mieux que je ne le pourrais jamais. Vous devriez lire son billet. Mais pour des raisons de concision, je vais essayer de le résumer :

  • « Les tâches de base peuvent toujours être réalisées sans JavaScript. »
  • Les tâches de base devraient être réalisées sur la couche la plus stable (c’est-à-dire pas JavaScript).
  • Les améliorations progressives ne sont pas anti-JavaScript. Il s’agit simplement d’adopter les bonnes technologies sur la bonne couche.
  • « Parce qu’il y a une certaine chance que JavaScript ne fonctionne pas, nous devons toujours tenir compte de cette chance. »
  • Ce n’est jamais une bonne idée d’ignorer les utilisateurs potentiels.
  • L’amélioration progressive est juste une bonne ingénierie.

Donc, nous allons faire autant que nous pouvons avec HTML et CSS. Puis faire en sorte que JavaScript fasse sa magie sur une couche plus appropriée – en améliorant l’interface utilisateur déjà existante.

Etape 1 : HTML

Comme vous le savez peut-être, la première étape consiste toujours à écrire une couche de base solide et bien pensée de HTML.

Note : J’utilise Font Awesome pour les icônes dans mon exemple.

Étape 1 : HTML initial pour un menu hamburger réactif purement CSS

Semble plutôt standard, non ? Nous avons :

  • Notre élément parent <header>
  • L’icône hamburger (« fa-bars »)
  • Un titre principal (ou potentiellement un logo)
  • La navigation dans un élément <nav>
  • Une icône de fermeture (« fa-close ») à l’intérieur de la navigation (on y reviendra plus tard)
  • Un « backdrop » après la navigation. Pourquoi s’agit-il d’une balise d’ancrage ? Je l’expliquerai plus tard.

Étape 2 : Rendons-le plus accessible

L’accessibilité ne devrait jamais être une pensée après coup – comme après avoir écrit votre application. Elle devrait être planifiée dès le début. L’ajout de quelques considérations de base maintenant améliorera non seulement l’accessibilité globale de votre site, mais vous fournira (au développeur) un meilleur balisage à utiliser dans votre JavaScript !

Avec cela, nous allons ajouter quelques attributs supplémentaires et du texte réservé aux lecteurs d’écran :

Étape 2 : Améliorer le HTML pour qu’il soit plus accessible.

Voici une ventilation rapide de tous ces attributs et de leur fonctionnement :

  • Nous avons ajouté des ID uniques pour cibler nos HREF (plus sur la façon dont cela fonctionne plus tard).
  • Nous avons fourni un libellé informatif des boutons pour les lecteurs d’écran à l’aide de .
  • Nous avons masqué les icônes aux lecteurs d’écran avec , car il s’agit de représentations visuelles, et ajouté du texte réservé aux lecteurs d’écran avec les éléments <span class= »sr-only »>.
  • Nous avons retiré le « backdrop » de l’index de tabulation avec un . Il est de nature purement visuelle et nous ne voulons pas confondre nos utilisateurs malvoyants et ceux qui n’utilisent que le clavier.
  • Nous avons ajouté l’attribut amazing pour définir l’état initial (et sémantique) du « backdrop ». Plus de déchets – comme c’est excitant!

Voici le résultat jusqu’à présent:

Figure 1 : Affichage résultant du HTML après les étapes 1 et 2.

Etape 3 : stylons-le !

Nous allons aborder cela d’abord par le mobile, donc éliminons la vue mobile, « hamburger-y » (la partie intéressante).

D’abord, nous allons juste obtenir la mise en page de l’en-tête correctement (sans l’interactivité):

Étape 3 : Ajouter un peu de CSS pour styliser l’en-tête (sans interactivité, pour le moment).

Le résultat:

Figure 2 : Affichage résultant du HTML & CSS après l’étape 3.

Étape 4 : Interactivité avec CSS pur

Lorsque vous rendez les widgets interactifs avec CSS, vous avez deux options :

  1. Utiliser des radios ou des cases à cocher
  2. Utiliser la pseudo-classe :target.

Les radios et les cases à cocher fonctionnent étonnamment bien pour la plupart des widgets, comme les onglets, les modales, les dropdowns et les accordéons. Chris Coyier a surnommé cette technique « le hack des cases à cocher ». Plusieurs développeurs ont utilisé ce « hack » pour leurs menus off-canvas, comme dans le tutoriel de Paul Lewis pour le Chrome Dev Summit ou le menu hamburger morphing de Luis Manuel.

Cependant, la pseudo-classe :target est plus sémantique dans ce cas d’utilisation, puisque nous traitons directement de la navigation. Vous pouvez ne pas être d’accord, et c’est tout à fait correct ! Il serait incroyablement facile et parfaitement acceptable de troquer la pseudo-classe :target contre une case à cocher.

L’une ou l’autre technique a cependant ses mises en garde.

L’utilisation d’une case à cocher :

  • Demande à JavaScript de fermer le menu hors toile si l’un des liens du menu était un lien d’ancrage vers une section spécifique de la même page.
  • Demande au champ <input> d’être un frère du menu ou au moins un frère de l’ancêtre du menu. En d’autres termes, le CSS est un peu plus délicat. Vous pouvez avoir le <label> (même plusieurs étiquettes) ailleurs, cependant.
  • L’élément <label> ne sera pas directement focalisable ou tabulable, ce qui nécessite un CSS un peu plus délicat pour gérer le focus sur la case à cocher tout en changeant l’apparence visible du <label>.
  • La navigation au clavier autour de l’ouverture/fermeture du menu sera bancale. Affecter un changement d’état sur une case à cocher se fait par la touche et non par la touche . Alors que les utilisateurs aveugles peuvent comprendre que le widget est actionné par une case à cocher, les utilisateurs de clavier voyants seront confus puisque la case à cocher n’est pas apparente – quelque chose que j’ai ressenti comme un bris d’accord dans ce cas d’utilisation.

Utilisation de la pseudo-classe :target:

  • Ajoute l’ouverture/fermeture du menu hors toile à l’historique du navigateur (en poussant le hachage dans la barre d’adresse). Il faudra que JavaScript exécute Event.preventDefault() pour éviter cela (et le saut potentiellement gênant en haut de la page).

Et il peut y avoir d’autres mises en garde que j’ai manquées. Quoi qu’il en soit, le choix de la technique est à la fois une question de préférence et soumis aux exigences de votre projet. Quoi qu’il en soit, j’ai fait une digression…

Voici la partie interactive du CSS:

Etape 4 : Ajouter du CSS pour l’interactivité.

Le résultat lorsqu’on clique dessus:

Figure 3 : Affichage résultant du menu hamburger lorsqu’il est ouvert.

Comment tout cela fonctionne

Essentiellement, la pseudo-classe :target nous donne un nouvel « état » pour styliser la navigation ciblée. Lorsque main-menu a été ciblé (avec son hash ajouté à l’URL), nous pouvons maintenant faire glisser le menu. C’est un peu comme une pseudo-classe :focus pour l’élément ciblé (pas le lien lui-même).

Nous avons également permis à la « toile de fond » de s’afficher lorsque la navigation est ciblée.

Vous remarquerez que l’icône hamburger principale est liée à l’ID de la navigation, tandis que l’icône de fermeture et les boutons de toile de fond sont liés à l’icône hamburger principale. Cela nous permet de cliquer sur l’icône de fermeture ou sur le bouton d’arrière-plan pour supprimer le « focus » – ou en fait la « cible » – de la navigation. Si le backdrop n’était pas un lien, il ne serait pas cliquable sans JavaScript.

J’ai également enchaîné les sélecteurs :target avec l’attribut dans le CSS. Ce sera éventuellement l’endroit où nous améliorons progressivement le menu hamburger avec JavaScript pour ne pas sauter à l’en-tête lorsqu’il est cliqué – en évitant la mise en garde que j’ai mentionnée précédemment. Si le JavaScript détourne le comportement de hachage du navigateur, la pseudo-classe :target ne fonctionnera plus. Lorsque cela se produira, nous profiterons de l’attribut pour styliser le basculement avec des valeurs vrai/faux, un peu comme nous aurions pu le faire dans le passé avec des classes.

En attendant, cependant, cela fonctionne magnifiquement sans JavaScript.

J’ai ajouté la requête média @supports pour fournir la position préférée :fixed CSS aux navigateurs (mobiles et de bureau) qui la supportent. Sinon, les navigateurs et appareils boiteux – je vous regarde iOS – obtiendront position:absolute.

Étape 5 : Styles pour écrans plus grands

Puisque nous ne voulons pas que le menu hamburger s’affiche pour les appareils non mobiles (ou les écrans plus grands en général), nous ajouterons la requête média nécessaire à cet effet. Ensuite, nous allons le styliser pour qu’il ressemble à une navigation horizontale :

Étape 5 : CSS pour styliser la navigation sur des écrans plus grands.

Le résultat:

Figure 4 : Affichage résultant de la navigation stylisée pour de plus grands écrans.

Voila ! Nous avons terminé!

Mise en forme

Voici le HTML final:

HMAGE final pour le menu hamburger réactif utilisant uniquement CSS.

Voici le CSS final:

CSS final pour le menu hamburger responsive.

Demo

Essayez vous-même mon CodePen:
→ Pure CSS Hamburger Menu sans JavaScript.

Note : vous pouvez également faire la démo de la version checkbox du menu.

Vous voulez ajouter du JavaScript pour le rendre plus lisse ?

Bien que nous puissions faire fonctionner le menu hors toile entièrement avec CSS – améliorant ainsi ses performances et sa fiabilité – nous aurons toujours besoin de JavaScript pour aider d’une certaine manière à améliorer l’interactivité entourant les inconvénients de l’une ou l’autre technique. Vous pouvez également utiliser JavaScript pour empêcher le défilement sur la page lorsque le menu est ouvert.

Il convient également de noter qu’un niveau décent (et sans doute le niveau le plus important) d’accessibilité peut être atteint sans JavaScript. Cependant, il est difficile de fournir un niveau d’accessibilité robuste sans la capacité de JavaScript à manipuler le DOM (par exemple, la gestion du focus, les mises à jour des attributs ARIA, etc.)

Pour plus d’informations sur l’amélioration de votre site Web par le biais de JavaScript, consultez les articles suivants :

  • Utilisation des attributs ARIA pour le réglage de l’état de JavaScript &style
  • Écrire JavaScript avec l’accessibilité à l’esprit

Avez-vous d’autres pensées ou suggestions ?

J’aimerais entendre vos commentaires avec mon approche d’un menu hamburger purement CSS.

Éditions et ruminations ultérieures

Le 21 janvier 2019 : édition de l’article et mise à jour des exemples de code pour supprimer les attributs ARIA inutiles et améliorer l’accessibilité.

A mesure que j’en ai appris davantage sur l’utilisation d’ARIA et le développement de &tests pour l’accessibilité en général, j’ai réalisé plusieurs choses :

  1. JavaScript a définitivement sa place, et devrait faire partie de tout modèle d’interface utilisateur d’accessibilité robuste.
  2. À l’exception des points de repère ARIA, JavaScript est nécessaire pour utiliser ARIA correctement. Et, beaucoup des attributs que j’ai utilisés, comme sont mieux laissés pour JavaScript à ajouter une fois chargé au lieu de l’ajouter directement dans le balisage. Ce concept suit les bonnes pratiques d’amélioration progressive – les états et les propriétés ARIA ainsi que JavaScript sont une mise à niveau et devraient être gérés sur une couche distincte.
  3. Auparavant, je ne gérais pas le focus correctement car le focus disparaissait au fur et à mesure qu’il progressait dans les liens visuellement cachés (lorsqu’ils étaient rabattus). J’ai ajouté un display : none ; au CSS du menu pour corriger cela.

Donc, si vous avez mis en œuvre une version précédente de mon Pure CSS Off-Canvas Hamburger Menu, s’il vous plaît envisager de le mettre à jour à cette version plus simple et plus accessible!

.

Laisser un commentaire

Votre adresse e-mail ne sera pas publiée.