La plupart du temps, les solutions de navigation mobile sur petits écrans utilisent du Javascript pour faire apparaître ou disparaître le menu quand on clique sur un bouton. C’est souvent top. On clique sur l’hamburger et hop, le menu glisse du haut de l’écran, d’un des côtés ou se déroule juste sous le logo.
Le problème c’est que sur certains sites que je visite souvent, il faut que j’attende un moment avant de pouvoir naviguer. Surtout sur mobile. Je tape l’adresse et la page apparaît avec le bouton en haut à droite. Je sais où je vais donc je clique le bouton, et j’attends. Je clique encore. Rien. Je regarde en bas de mon écran près de l’adresse… En fait, la page n’est pas encore totalement chargée. Il faut que j’attende que les scripts du bas de la page soient chargés et exécutés. Super …
Sur un site que je visite pour la première fois, ça ne pose pas de problème car j’ai le temps. J’explore, je découvre. Je découvre le logo, puis je lis le texte de l’entête. Puis je défile un peu pour lire le contenu et voir où je suis tombé. Quand j’ai fini, je remonte vers le menu pour l’ouvrir et voir ce qu’on me propose.
Par contre quand je connais bien le site et que j’y vais souvent, ça m’agace un peu de devoir attendre trois bonnes secondes avant d’aller où je veux. Surtout si le contenu est déjà dispo. Cliquer plusieurs fois sur un bouton inactif c’est pas top niveau UX, quand même.
Dans cet article, je vais vous montrer comment coder une navigation mobile sans Javascript. Juste de l’HTML et du CSS. Ce qui veut dire que dès que l’HTML et le CSS sont chargés, le bouton est dispo. Pas besoin d’attendre que le script du bas de la page soit chargé. Une navigation fiable et rapide.
Voilà une vidéo qui vous résume un peu le principe. Il n’y a pas tous les styles décrits ci-dessous, mais l’essentiel y est. Si vous voulez juste lire tout le code, continuez.
D’abord l’HTML
Pour la démo, on va utiliser un document HTML tout ce qu’il y a de plus simple et standard.
[pastacode lang=”markup” manual=”%3C!DOCTYPE%20html%3E%0A%3Chtml%20class%3D%22no-js%22%3E%0A%3Chead%3E%0A%09%3Cmeta%20charset%3D%22utf-8%22%20%2F%3E%0A%09%3Cmeta%20name%3D%22viewport%22%20content%3D%22width%3Ddevice-width%2C%20initial-scale%3D1%22%20%2F%3E%0A%09%3Clink%20rel%3D%22stylesheet%22%20href%3D%22style.css%22%20type%3D%22text%2Fcss%22%20%2F%3E%0A%20%20%20%20%3Clink%20rel%3D%22stylesheet%22%20href%3D%22navigation.css%22%20type%3D%22text%2Fcss%22%3E%0A%20%20%20%20%3Clink%20href%3D%22https%3A%2F%2Ffonts.googleapis.com%2Fcss%3Ffamily%3DProza%2BLibre%3A400%2C400i%22%20rel%3D%22stylesheet%22%3E%0A%3C%2Fhead%3E%0A%0A%3Cbody%3E%0A%20%20%20%20%3Cheader%20class%3D%22main-header%22%3E%0A%0A%20%20%20%20%20%20%20%20%3Cnav%20class%3D%22main-navigation%22%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3Cdiv%20class%3D%22nav-wrapper%22%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3Cp%20class%3D%22site-title%22%3EPure%20CSS%20mobile%20navigation%3C%2Fp%3E%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3Cul%20class%3D%22menu%22%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3Cli%3E%3Ca%20href%3D%22%22%3EMenu%20item%201%3C%2Fa%3E%3C%2Fli%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3Cli%3E%3Ca%20href%3D%22%22%3EMenu%20item%202%3C%2Fa%3E%3C%2Fli%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3Cli%3E%3Ca%20href%3D%22%22%3EMenu%20item%203%3C%2Fa%3E%3C%2Fli%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3Cli%3E%3Ca%20href%3D%22%22%3EMenu%20item%204%2C%20but%20with%20a%20lot%20more%20text%3C%2Fa%3E%3C%2Fli%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3C%2Ful%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3C%2Fdiv%3E%20%0A%20%20%20%20%20%20%20%20%3C%2Fnav%3E%0A%0A%20%20%20%20%20%20%20%20%3Cdiv%20class%3D%22hero-section%22%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3Ch1%20class%3D%22hero-title%22%3EPure%20CSS%20mobile%20navigation%3C%2Fh1%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3Cp%20class%3D%22hero-description%22%3EPas%20besoin%20de%20Javascript%20pour%20cr%C3%A9er%20une%20navigation%20mobile%20responsive.%3C%2Fp%3E%0A%20%20%20%20%20%20%20%20%3C%2Fdiv%3E%0A%20%20%20%20%20%20%20%20%0A%20%20%20%20%3C%2Fheader%3E%0A%0A%20%20%20%20%3Cmain%20class%3D%22main-content%22%3E%0A%20%20%20%20%20%20%20%20%3Cp%3EProblems%20look%20mighty%20small%20from%20150%20miles%20up.%3C%2Fp%3E%0A%20%20%20%20%20%20%20%20%3Cp%3ESpaceflights%20cannot%20be%20stopped.%20This%20is%20not%20the%20work%20of%20any%20one%20man%20or%20even%20a%20group%20of%20men.%20It%20is%20a%20historical%20process%20which%20mankind%20is%20carrying%20out%20in%20accordance%20with%20the%20natural%20laws%20of%20human%20development.%3C%2Fp%3E%0A%20%20%20%20%20%20%20%20%3Cp%3EA%20Chinese%20tale%20tells%20of%20some%20men%20sent%20to%20harm%20a%20young%20girl%20who%2C%20upon%20seeing%20her%20beauty%2C%20become%20her%20protectors%20rather%20than%20her%20violators.%20That’s%20how%20I%20felt%20seeing%20the%20Earth%20for%20the%20first%20time.%20I%20could%20not%20help%20but%20love%20and%20cherish%20her.%3C%2Fp%3E%0A%20%20%20%20%3C%2Fmain%3E%0A%0A%20%20%20%20%3Cfooter%20class%3D%22main-footer%22%3E%0A%20%20%20%20%20%20%20%20%3Cdiv%20class%3D%22footer-wrapper%22%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3Cp%3EThis%20is%20just%20the%20footer.%20There%20is%20nothing%20to%20see%20here.%3C%2Fp%3E%0A%20%20%20%20%20%20%20%20%3C%2Fdiv%3E%0A%20%20%20%20%3C%2Ffooter%3E%0A%3C%2Fbody%3E” message=”” highlight=”” provider=”manual”/]
Dans la balise <head>
, je charge deux feuilles de styles. La première, style.css
, contient juste quelques lignes pour normaliser les styles par défaut et rendre la démo un peu plus jolie. Rien de super palpitant.
La deuxième feuille de style est celle dans laquelle on va bosser et ajouter le CSS qui va rendre notre navigation fonctionnelle. Pour l’instant, elle est vide.
Enfin, je charge une police de caractère pour faire joli. Optionnel, mais sympa pour la démo.
Dans la balise <body>
, on commence par un <header>
avec deux éléments : notre barre de navigation <nav class="main-navigation">
avec le titre du site et le menu, puis une entête <div class="hero-section">
avec le titre et un sous-titre. Tout simple.
Puis une zone de contenu <main class="main-content">
avec trois paragraphes de ZombieIpsum, et un <footer class="main-footer">
qui n’a rien de spécial.
Les quelques styles présents dans style.css
sont d’ordre purement cosmétiques. Si vous parcourez style.css
, vous verrez qu’il n’y a que des styles pour normaliser et quelques ajouts simples de padding, marges et typographie.
On va travailler uniquement dans navigation.css
. Et comme on va s’appliquer à créer une navigation pour mobile, on va réduire la fenêtre du navigateur jusqu’à la taille d’un smartphone pour commencer.
Principe et mise en oeuvre
Ce qu’on veut, c’est faire un bouton apparent sur mobiles qui va permettre d’afficher ou de cacher la navigation. On cherche donc à gérer uniquement deux états: affiché/caché.
Pour ça, on va utiliser une simple checkbox, car une checkbox a uniquement deux états: coché ou non, et on va se servir de ces deux états pour afficher ou cacher le menu voisin dans l’HTML.
Dans index.html
, on va donc ajouter notre checkbox juste à côté de la liste <ul class="menu">
, et on va en profiter pour lui rajouter une classe pour pouvoir la cibler dans notre feuille de styles.
[pastacode lang=”markup” manual=”%3Cinput%20type%3D%22checkbox%22%20class%3D%22menu-checkbox%22%20%2F%3E%0A%3Cul%20class%3D%22menu%22%3E%0A%09%3Cli%3E%3Ca%20href%3D%22%22%3EMenu%20item%201%3C%2Fa%3E%3C%2Fli%3E%0A%09%E2%80%A6%0A%3C%2Ful%3E” message=”” highlight=”1″ provider=”manual”/]
Si on rafraîchit notre page, on peut voir la checkbox, mais elle ne sert à rien pour l’instant. Il faut maintenant dire à notre feuille de style de cacher le menu par défaut, et de le montrer uniquement quand la checkbox est cochée.
Dans navigation.css
, pour que le menu soit caché par défaut, on va ajouter:
[pastacode lang=”css” manual=”.menu%20%7B%0A%20%20%20%20display%3A%20none%3B%0A%7D” message=”” highlight=”” provider=”manual”/]
Puis, on va utiliser une pseudo classe :checked
et un sélecteur CSS de ninja pour sélectionner le menu <ul class="menu">
suivant la checkbox uniquement quand celle-ci est cochée.
[pastacode lang=”css” manual=”.menu-checkbox%3Achecked%20~%20.menu%20%7B%0A%20%20%20%20display%3A%20block%3B%0A%7D” message=”” highlight=”” provider=”manual”/]
Avec le “~” on sélectionne les éléments ayant pour classe .menu
précédés d’un élément ayant pour classe .menu-checkbox
. Avec la pseudo classe :checked
, on s’assure de sélectionner .menu
uniquement si .menu-checkbox
est cochée.
Et voilà ! C’est fonctionnel ! En cliquant la checkbox, on fait apparaître et disparaître le menu !
Un beau bouton
Bon, notre navigation fonctionne, mais c’est pas très joli. On va améliorer tout ça.
Déjà, je vais remplacer la checkbox par un bouton hamburger en utilisant l’entité HTML ≡
, avec un petit texte. Pour ça, on va utiliser un élément <label>
.
On va simplement placer un <label>
et le lier à la checkbox. En liant le <label>
à la checkbox, on va pouvoir cocher/décocher la checkbox en cliquant sur ce <label>
. Pour ça, on va ajouter à notre checkbox un identifiant correspondant à l’attribut for
du <label>
.
[pastacode lang=”markup” manual=”%3Cinput%20type%3D%22checkbox%22%20id%3D%22menu-checkbox%22%20class%3D%22menu-checkbox%22%3E%0A%3Clabel%20for%3D%22menu-checkbox%22%20class%3D%22menu-toggle%22%3E%26equiv%3B%20Menu%3C%2Flabel%3E%0A%3Cul%20class%3D%22menu%22%3E%0A%09%3Cli%3E%3Ca%20href%3D%22%22%3EMenu%20item%201%3C%2Fa%3E%3C%2Fli%3E%0A%09%E2%80%A6%0A%3C%2Ful%3E” message=”” highlight=”1-2″ provider=”manual”/]
Maintenant, quand on clique le mot ‘Menu’ ou l’icône du burger, le menu apparaît. On peut donc supprimer cette checkbox. On pourrait supprimer la checkbox avec un simple display: none;
mais cela pose un problème d’accessibilité sur desktop. Le problème ne se pose pas sur mobile, mais si vous voulez garder votre navigation cachée derrière un bouton sur grand écran, il vaut mieux éviter.
En effet, un display: none;
supprime aussi la checkbox pour la navigation au clavier, et même si on peut cliquer un <label>
pour cocher la checkbox, un <label>
ne peut pas recevoir de focus. Il est donc inopérable au clavier. Il a besoin de sa checkbox accessible. Accessible pas visuellement, mais au moins au clavier. On la cache donc avec un position: absolute;
[pastacode lang=”css” manual=”.menu-checkbox%20%7B%0A%09opacity%3A%200%3B%0A%09position%3A%20absolute%3B%0A%09top%3A%20-1000px%3B%0A%7D” message=”” highlight=”” provider=”manual”/]
Par contre, pour mettre en évidence que la checkbox est sous focus pour les utilisateurs navigant au clavier, on va utiliser un autre sélecteur de ninja.
[pastacode lang=”css” manual=”.menu-checkbox%3Afocus%20%2B%20.menu-toggle%20%7B%0A%20%20%20%20outline%3A%20%2300A1A1%20auto%205px%3B%0A%7D%0A%0A.menu-toggle%20%7B%0A%20%20%20%20padding%3A%20.5em%201em%3B%0A%7D” message=”” highlight=”” provider=”manual”/]
Ici, on sélectionne notre <label>
avec la classe .menu-toggle
s’il est adjacent (“+”) à notre checkbox cochée et on lui ajoute une outline. Ce qui veut dire que le <label>
aura un joli cadre quand la checkbox recevra le focus. Un utilisateur voyant, mais naviguant au clavier saura donc qu’il peut ouvrir le menu quand il aura placé le focus sur la checkbox.
Un peu de mise en page
C’est déjà bien mieux. La checkbox a disparu, et on a un bouton à la place.
Mais on va mettre ce bouton en haut à droite, aligné avec le titre. On pourrait faire un simple float
pour ça, mais on va faire mieux. On va utiliser flexbox.
En utilisant display: flex;
sur notre <div class="nav-wrapper">
(qui deviendra le conteneur flex), on va pouvoir lui dire d’afficher ses enfants en file indienne de gauche à droite.
Dans notre navigation.css
, on ajoute:
[pastacode lang=”css” manual=”.nav-wrapper%20%7B%0A%20%20%20%20display%3A%20flex%3B%0A%7D” message=”” highlight=”” provider=”manual”/]
Et hop, le bouton se retrouve collé au titre, juste à sa droite. On va utiliser les propriétés justify-content
et align-items
pour s’assurer que le bouton aille bien se caler à droite et soit parfaitement aligné verticalement avec le titre.
[pastacode lang=”css” manual=”.nav-wrapper%20%7B%0A%20%20%20%20align-items%3A%20center%3B%0A%20%20%20%20display%3A%20flex%3B%0A%20%20%20%20justify-content%3A%20space-between%3B%0A%7D” message=”” highlight=”2, 4″ provider=”manual”/]
justify-content: space-between;
va permettre d’espacer le plus possible les éléments à l’intérieur de .nav-wrapper
, et align-items: center;
va permettre de les centrer verticalement.
Maintenant, on a un problème. Quand on clique le bouton pour faire apparaître le menu, celui-ci apparaît à droite au lieu d’en-dessous !
Evidemment ! On a demandé à .nav-wrapper
d’aligner ses enfants grâce à display: flex
, qu’il y en ait deux, trois, ou même dix!
On peut sortir le menu du flow du document avec un position:absolute;
, ou alors utiliser les propriétés de flexbox pour régler le problème.
On va simplement dire à .nav-wrapper
de renvoyer ses enfants à la ligne en-dessous quand il n’arrive pas à tous les caser sur la même ligne sans les écraser un peu.
[pastacode lang=”css” manual=”.nav-wrapper%20%7B%0A%20%20%20%20align-items%3A%20center%3B%0A%20%20%20%20display%3A%20flex%3B%0A%20%20%20%20flex-wrap%3A%20wrap%3B%0A%20%20%20%20justify-content%3A%20space-between%3B%0A%7D” message=”” highlight=”4″ provider=”manual”/]
Sur tout petit écran, ça marche sans soucis. Notre menu est renvoyé en dessous car il n’y a plus de place pour lui sur la ligne au-dessus. Il se comporte comme du texte simple, en fait. Et l’espace supérieur est utilisé complètement par le titre et le bouton.
Mais si on agrandit la fenêtre du navigateur, le menu vient se remettre sur la ligne supérieure dés qu’il en a la place. Plus le menu est large, plus il lui faut de place, mais ça finit toujours par arriver.
J’ai mis un long lien en quatrième position exprès pour vous montrer. Si vous réduisez ce lien en coupant le texte, le menu prends moins de place et a plus de facilités à venir se recaler en haut à côté de notre bouton.
Et on veut qu’il reste en dessous, quelle que soit sa taille. Donc, pour être sûr que .menu
reste en dessous sur une nouvelle ligne quelle que soit sa largeur, on va lui réserver toute la largeur du conteneur avec flex-basis
.
[pastacode lang=”css” manual=”.menu%20%7B%0A%20%20%20%20flex-basis%3A%20100%25%3B%0A%7D” message=”” highlight=”” provider=”manual”/]
Ici, on demande à .nav-wrapper
(le conteneur flex) de réserver 100% de sa largeur à son enfant .menu
. Il tombera donc toujours en dessous. Ouf, le menu reste en dessous quelle que soit la largeur de la fenêtre.
Transitions
Notre menu fonctionne correctement, mais passer de display: none;
à display: block;
c’est un peu abrupte. On va embellir et fluidifier tout ça.
D’abord, concernant notre menu, on va enlever notre display: none;
par défaut pour le remplacer par :
[pastacode lang=”css” manual=”.menu%20%7B%0A%20%20%20%20flex-basis%3A%20100%25%3B%0A%20%20%20%20max-height%3A%200%3B%0A%20%20%20%20overflow%3A%20hidden%3B%0A%7D” message=”” highlight=”3-4″ provider=”manual”/]
Puis on remplace notre display: block;
quand la checkbox est cochée par:
[pastacode lang=”css” manual=”.menu-checkbox%3Achecked%20%2B%20.menu%20%7B%0A%20%20%20%20max-height%3A%201000px%3B%0A%7D” message=”” highlight=”2″ provider=”manual”/]
Au lieu de supprimer complètement le menu, on lui donne une hauteur nulle pour le cacher.
Mais le souci, c’est qu’il a beau avoir une hauteur nulle, il conserve ses marges, et c’est pour ça que la barre de navigation est agrandie. En inspectant le code, on voit bien les marges de notre menu.
On va donc lui enlever ses marges et les lui remettre quand il est ouvert.
[pastacode lang=”css” manual=”.menu%20%7B%0A%20%20%20%20flex-basis%3A%20100%25%3B%0A%20%20%20%20margin%3A%200%3B%0A%20%20%20%20max-height%3A%200%3B%0A%20%20%20%20overflow%3A%20hidden%3B%0A%7D%0A%0A.menu-checkbox%3Achecked%20%2B%20.menu%20%7B%0A%20%20%20%20margin%3A%201em%200%3B%0A%20%20%20%20max-height%3A%20none%3B%0A%7D” message=”” highlight=”3-9″ provider=”manual”/]
Pour dérouler le menu de façon fluide, on va ajouter une transition sur les marges, l’opacité, et la hauteur.
[pastacode lang=”css” manual=”.menu%20%7B%0A%20%20%20%20margin%3A%200%3B%0A%20%20%20%20max-height%3A%200%3B%0A%20%20%20%20opacity%3A%200%3B%0A%20%20%20%20overflow%3A%20hidden%3B%0A%20%20%20%20transition%3A%20margin%20.5s%20ease-in-out%2C%20max-height%20.5s%20ease-in-out%2C%20opacity%20.3s%20.1s%20ease-in-out%2C%0A%7D%0A%0A.menu-checkbox%3Achecked%20%2B%20.menu%20%7B%0A%20%20%20%20margin%3A%201em%200%3B%0A%20%20%20%20max-height%3A%201000px%3B%0A%20%20%20%20opacity%3A%201%3B%0A%7D” message=”” highlight=”6, 12″ provider=”manual”/]
Le soucis d’accessibilité au clavier se pose encore ici. Les éléments du menu ont beau être cachés visuellement, ils sont accessibles au clavier !
Ce qui veut dire que si l’on met en focus le bouton du menu, puis qu’on continue à appuyer sur TAB, on parcourt les liens de notre menu sans le savoir, alors qu’on devrait directement tomber sur le premier élément hors de ce menu qui peut recevoir le focus.
On va donc rajouter un simple visibility: hidden;
quand le menu est caché. visibility
permet de cacher/montrer aussi les liens de notre menu aux screen readers.
[pastacode lang=”css” manual=”.menu%20%7B%0A%20%20%20%20margin%3A%200%3B%0A%20%20%20%20max-height%3A%200%3B%0A%20%20%20%20opacity%3A%200%3B%0A%20%20%20%20overflow%3A%20hidden%3B%0A%20%20%20%20transition%3A%20margin%20.5s%20ease-in-out%2C%20max-height%20.5s%20ease-in-out%2C%20opacity%20.3s%20.1s%20ease-in-out%3B%0A%20%20%20%20visibility%3A%20hidden%3B%0A%7D%0A%0A.menu-checkbox%3Achecked%20%2B%20.menu%20%7B%0A%20%20%20%20margin%3A%201em%200%3B%0A%20%20%20%20max-height%3A%20500px%3B%0A%20%20%20%20opacity%3A%201%3B%0A%20%20%20%20visibility%3A%20visible%3B%0A%7D” message=”” highlight=”7, 14″ provider=”manual”/]
Maintenant, en appuyant sur TAB, je tombe au-delà du menu s’il est fermé. S’il est ouvert, je peux parcourir les liens.
Maintenant, on va rajouter quelques styles pour rendre le menu plus joli.
[pastacode lang=”css” manual=”.menu%20%7B%0A%C2%A0%C2%A0%C2%A0%20flex-basis%3A%20100%25%3B%0A%C2%A0%C2%A0%C2%A0%20list-style%3A%20none%3B%0A%C2%A0%C2%A0%C2%A0%20margin%3A%200%3B%0A%C2%A0%C2%A0%C2%A0%20max-height%3A%200%3B%0A%C2%A0%C2%A0%C2%A0%20opacity%3A%200%3B%0A%C2%A0%C2%A0%C2%A0%20overflow%3A%20hidden%3B%0A%C2%A0%C2%A0%C2%A0%20padding%3A%200%202em%3B%0A%C2%A0%C2%A0%C2%A0%20text-transform%3A%20uppercase%3B%0A%C2%A0%C2%A0%C2%A0%20transition%3A%20margin%20.5s%20ease-in-out%2C%20max-height%20.5s%20ease-in-out%2C%20opacity%20.3s%20.1s%20ease-in-out%3B%0A%7D%0A%0A.menu%20li%20%7B%0A%C2%A0%C2%A0%C2%A0%20border-bottom%3A%201px%20solid%20%23eee%3B%0A%7D%0A%0A.menu%20li%20a%20%7B%0A%C2%A0%C2%A0%C2%A0%20display%3A%20inline-block%3B%0A%C2%A0%C2%A0%C2%A0%20padding%3A%200.5em%201em%3B%0A%7D” message=”” highlight=”3-7-8-13-18″ provider=”manual”/]
Voilà, c’est suffisant pour notre exemple.
Le menu sur desktop
Maintenant, on va s’occuper de notre menu sur grand écran. Pour l’instant, le menu garde le même aspect et garde son bouton sur grand écran.
On va faire en sorte que le bouton disparaisse et que les liens du menu s’affichent en ligne, à droite de la barre de navigation.
On va donc travailler dans une media query, et on va commencer par supprimer le bouton et rendre au menu sa visibilité.
[pastacode lang=”css” manual=”%40media%20screen%20and%20(min-width%3A%2065em)%20%7B%0A%C2%A0%C2%A0%C2%A0%20.menu%20%7B%0A%20%20%20%20%20%20%20%20margin%3A%200%3B%0A%20%20%20%20%20%20%20%20max-height%3A%201000px%3B%0A%20%20%20%20%20%20%20%20opacity%3A%201%3B%0A%20%20%20%20%20%20%20%20padding%3A%200%3B%0A%20%20%20%20%20%20%20%20visibility%3A%20visible%3B%0A%C2%A0%C2%A0%C2%A0%20%7D%0A%0A%C2%A0%C2%A0%C2%A0%20.menu-toggle%2C%0A%C2%A0%C2%A0%C2%A0%20.menu-checkbox%20%7B%0A%20%20%20%20%20%20%20%20display%3A%20none%3B%0A%C2%A0%C2%A0%C2%A0%20%7D%0A%7D” message=”” highlight=”” provider=”manual”/]
Quand on agrandit la fenêtre, notre menu apparaît bien, mais il reste en dessous du titre. C’est parce qu’on lui a réservé 100% de la largeur. Il faut lui demander de prendre uniquement la place dont il a besoin.
[pastacode lang=”css” manual=”%40media%20screen%20and%20(min-width%3A%2065em)%20%7B%0A%C2%A0%C2%A0%C2%A0%20.menu%20%7B%0A%20%20%20%20%20%20%20%20flex-basis%3A%20auto%3B%0A%20%20%20%20%20%20%20%20margin%3A%200%3B%0A%20%20%20%20%20%20%20%20max-height%3A%201000px%3B%0A%20%20%20%20%20%20%20%20opacity%3A%201%3B%0A%20%20%20%20%20%20%20%20padding%3A%200%3B%0A%20%20%20%20%20%20%20%20visibility%3A%20visible%3B%0A%20%20%20%20%7D%0A%7D” message=”” highlight=”3″ provider=”manual”/]
Et voilà. Maintenant, on n’a plus qu’à enlever les bordures et mettre les liens en file indienne. On va réduire aussi le padding pour que les liens soient un peu plus serrés.
[pastacode lang=”css” manual=”%20%20%20%20.menu%20li%20%7B%0A%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%20%C2%A0border%3A%20none%3B%0A%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%20display%3A%20inline-block%3B%0A%C2%A0%C2%A0%C2%A0%20%7D%0A%0A%20%20%20%20.menu%20li%20a%20%7B%0A%20%20%20%20%20%20%20%20padding%3A%20.5em%3B%0A%20%20%20%20%7D” message=”” highlight=”” provider=”manual”/]
Conclusion
Notre menu est fonctionnel et surtout il est immédiatement accessible car il ne nécessite aucun Javascript !
J’espère que cette démo vous a aidé et vous a inspiré ! J’ai plein d’astuces comme celle-ci à vous montrer pour éviter au maximum le JavaScript qui ralentit vos pages et rendre votre site ultra rapide et lean.
Quand on y pense bien, c’est juste une checkbox et quelques lignes de CSS. Pas de JS ni pour les fonctionnalités ni pour les animations, pas de float dans des conteneurs aux dimensions hard codées.
Il faut admettre que Flexbox aide énormément pour ce genre de mise en page. Ce n’est pas pour rien que le thème actuellement sur ce site utilise uniquement Flexbox, et quasiment aucun script !
Personnellement, même si j’adore le JavaScript, j’évite au maximum d’en utiliser pour les raisons évoquées en introduction. La seule chose importante que cette navigation ne fait pas, c’est communiquer aux screen readers le changement d’état du menu. Mais ça, ça nécessite du JavaScript. Et en plus, l’utilisateur peut savoir si la checkbox est cochée ou non.
Je suis un gros gros fan de Flexbox, des animations et transitions CSS et de ce genre d’astuces de ninja, donc attendez-vous à en lire d’autres dans de prochains articles. En attendant, inscrivez-vous pour n’en rater aucune !
PS: Si vous avez aimé ce article et êtes intéressé pour apprendre à développer pour WordPress en utilisant les meilleures pratiques, jetez-un oeil à WPCookBook ! C’est un vrai livre de recettes WordPress pour apprendre à développer pour WordPress proprement et exploiter au maximum tous les outils et APIs mis à notre disposition. Inscrivez-vous pour être notifié de sa publication !