Wednesday, November 20, 2013

Menu de navigation avec amélioration progressive

 L'ouvrage "Adaptive Web Design" d'Aaron Gustafson, dont nous avons fait le retour de lecture récemment est un excellent condensé du principe de développement par "Amélioration Progressive" (progressive enhancement) dans le Web.Nous allons tenter de comprendre cette approche et en quoi elle est primordiale à travers un cas concret : la conception d'un menu de navigation responsive.L'amélioration progressive, ou "web design adaptatif", n'est pas une question de compatibilité. Il n'est pas question de savoir "dois-je supporter IE6 ou non ?", cela va au-delà de ces basses considérations :)L'enjeu est plutôt de comprendre :de quoi est composé le parc des agents utilisateurs et périphériques susceptibles de tirer information de votre site (navigateurs, moteurs de recherche, synthèses vocales, imprimantes, smartphones)le plus petit dénominateur commun à tous les agents utilisateurs afin que le contenu soit toujours restituéd'enrichir progressivement l'expérience utilisateur pour les agents utilisateurs qui supportent ces améliorationsPlus schématiquement, et selon Aaron Gustafson, l'amélioration progressive c'est passer d'une expérience minimale vers l'expérience exceptionnelle :Le contenu textuelLa sémantique HTMLL'enrichissement visuelL'interaction avec le visiteurL'accessibilitéNote : l'amélioration progressive possède son alter ego, la dégradation gracieuse. Cette dernière part du principe inverse : tous les navigateurs récents doivent être privilégiés, et l'on autorise des alternatives, bidouilles, scripts pour pallier les déficiences des anciens.Cette façon de percevoir les choses modifie sensiblement l'approche "compatibilité navigateurs". En effet, à partir du moment où le 1er niveau est atteint, le site est forcément "compatible" sur tous les agents utilisateurs. Tout les autres paliers contribuent à enrichir progressivement l'expérience de l'utilisateur.Bien que semblant basique à mettre en pratique, cette philosophie de conception a l'avantage de bien remettre les choses au point et à leur place.Et surtout, ça nous rappelle une priorité qui doit surclasser toutes les autres : n'entravez jamais l'accès au contenu.Et malheureusement, les entraves à l'accès au contenu sont plus nombreuses qu'on ne le croit :des liens, ou des navigations, ne fonctionnant qu'avec JavaScript ou Flashdes contenus masqués par défaut en CSSdes contenus en display: none alors qu'ils devraient être perceptibles aux lecteurs d'écrandes contenus "faussés" (des alt ou title ne servant que de conteneurs de mots-clés)des images, vidéos sans alternative textuelle ou sous-titragedes tailles de contenus minuscules et non agrandissablesetc.Passons aux choses sérieuses : mettons tout cela en pratique en prenant comme exemple un menu de navigation responsive.Voir la démonstrationRien de particulier à ce stade, il s'agit de conférer aux liens des contenus explicites :Accueil,À propos,Blog web,Alsacréations,Contact.Même hors de son contexte, ce contenu demeure explicite… à condition que tous les visiteurs connaissent ce qu'est un "blog" et savent ce qu'est "Alsacréations".Profitons-en pour les dépanner un peu et enrichissons l'information lorsqu'il le faut. Un attribut title sera parfait pour une infobulle :title="Alsacréations, communauté d'apprentissage web">N'abusez pas, comme on le voit souvent, de l'attribut title, en le casant sur tous vos liens. Il n'est utile que s'il véhicule une information supplémentaire. Si vous l'appliquez partout, vous ne ferez que parasiter la lecture des synthèses vocales.La sémantique commence par le choix judicieux et approprié des éléments HTML (balises) afin que les agents utilisateurs puissent exploiter leurs fonctions.Il m'a semblé naturel d'opter pour l'élément HTML5 , contenant une liste de liens (
    ,
  • , ). La présence des éléments de liste n'est pas obligatoire, c'est plus par habitude que par réelle nécessité.AccueilÀ proposBlog webAlsacréationsContactPour rappel, l'élément HTML5 n'est pas supporté par les anciennes versions d'Internet Explorer. Par exemple, pour IE8 et inférieur, vous devrez créer cet élément dans le DOM ou employer le célèbre polyfill HTML5Shim.Les liens d'évitement sont bénéfiques à la navigation clavier et pour les déficients visuels. Dans cette optique, ajoutons un identifiant (id) à la navigation afin de servir d'ancre aux liens d'évitement; Il nous servira également de marqueur plus tard pour JavaScript :id="navigation">Nous pourrions en profiter pour enrichir la sémantique via HTML5 microdata car la documentation Schema.org nous fournit des microdonnées spécifiques à la navigation d'un site web : il s'agit de SiteNavigationElement.Cependant, à l'heure actuelle, il faut bien avouer que nous ne savons pas très bien si cette microdonnée de navigation est déjà exploitée par les agents utilisateurs ou les moteurs de recherche. Libre à vous d'attendre un peu qu'elle se démocratise (ou pas) avant de l'employer en production.Allez hop ! On passe à l'étape graphique, l'enrichissement le plus perceptible. Mais cela demeure un enrichissement comme un autre, rien de plus.Nous allons appliquer les styles CSS en gardant à l'esprit que tous les navigateurs ne supportent pas les dernières fioritures de CSS3.Cette navigation prendra forme en tenant compte des considérations d'ergonomie et d'accessibilité (taille de police, contrastes de couleurs, taille du lien cliquable). Quel que soit l'agent utilisateur, l'information doit être exploitable.Nous disposons de plusieurs moyens pour cibler le bloc de navigation en CSS :nous pouvons cibler directement l'élément (mais attention, il peut y avoir plusieurs dans une page),il est possible de se servir du sélecteur d'id (en ce qui me concerne, je ne suis pas très fan car il a trop de poids dans le calcul des sélecteurs),nous pourrions ajouter un attribut de type class="nav-main" (mais c'est peut-être un peu dommage de surcharger le code HTML pour cela),nous servir du sélecteur d'attribut via [id=navigation] ou encore [role=navigation] (que l'on aborde dans la dernière étape)Personnellement, j'ai fait le choix de cibler à l'aide de [id=navigation].Les styles de base demeureront très basiques :[id=navigation] ul {margin: 0; padding: 0;list-style: none;}[id=navigation] a {display: block;padding: 0.8em;background: #4A7377;color: #fff;text-decoration: none;}On passe à présent aux styles dédiés aux petits écrans. Pour cela, rien de mieux que des CSS3 media queries pour appliquer des styles aux fenêtres de moins de 768 pixels de large :@media (max-width: 767px) {...}Les media queries ne sont pas reconnus par IE8 et versions inférieures. Dans notre démarche d'amélioration progressive, cela n'est pas du tout un obstacle : les vieux IE disposeront de l'affichage de base. De plus, nous avons limité ces styles aux périphériques de fenêtre inférieure à 768px, donc généralement les smartphones… où ces antiques navigateurs n'existent pas !Pour les smartphones, l'opération principale consiste à générer en CSS un bouton d'action "burger" en caractère unicode qui symbolisera le menu quand il sera rétracté :[id=navigation]:after {content: "\2261"; /* symbole unicode du "burger" */position: absolute;top: -5.5rem; right: 4px;z-index: 42;width: 4rem;text-align: center;color: #000;font-size: 5rem;font-weight: bold;line-height: 1;}Tant qu'on y est, il pourrait être de bon ton de produire des améliorations visuelles (CSS) selon les périphériques. Par exemple :adapter la taille cliquable des liens selon la résolution (taille et DPI) des mobiles,modifier les contrastes ou passer la couleur de texte en noir sur imprimante,ajouter des fioritures graphiques pour navigateurs récents (coins arrondis, dégradés),etc.Lors du clic ou du touch sur le bouton "burger", le menu de navigation doit se rétracter ou se déployer.Pour ce faire, plusieurs techniques sont envisageables. Parmi celles-ci, nous avons choisi JavaScript notamment parce que ce langage se prête parfaitement à cette fonctionnalité. Mais sachez que d'autres langages (CSS) auraient pu faire l'affaire également.L'un des soucis de JavaScript est qu'il n'y a pas de tolérance à la panne : si JavaScript n'est pas activé ou est bloqué, le menu - qui est un contenu essentiel de la page - risque de ne pas être restitué car masqué.Pour nous assurer que le contenu de la navigation soit toujours accessible (1er palier), nous ajoutons la classe .nav-opened par défaut dans la balise  :class="nav-opened">Le menu doit être affiché et ouvert par défaut au chargement de la page. Ainsi, si JavaScript n'est pas activé, le menu demeurera déployé et fonctionnel.[id=navigation].nav-opened ul {max-height: 25em;}Au contraire, si JavaScript est fonctionnel, sa première mission sera de rétracter le menu en supprimant la classe .nav-opened.if (window.innerWidth<768) {t = document.getElementById('navigation'); if(t) {t.classList.toggle('nav-opened');t.onclick=function(){ t.classList.toggle('nav-opened');} }}Les styles suivants s'appliqueront alors :[id=navigation] ul {max-height: 0;overflow: hidden;}Pour information, on rétracte le menu en jouant sur une combinaison max-height + overflow, ce qui permettra de l'ouvrir progressivement via une transition CSS3 par la suite :-webkit-transition: max-height .4s;transition: max-height .4s;L'usage de JavaScript nécessite souvent d’implémenter des fonctionnalités et détections complémentaires qui complexifient le code initial mais en faciliteront l'emploi dans toutes les circonstances (onresize, timeout, zoom utilisateur, etc.). À vous de voir jusqu'où vous souhaitez parfaire le code minimal actuel.Parvenu à ce dernier palier, profitez-en pour refaire une dernière vérification de routine :Le contenu est-il toujours compréhensible hors contexte ?Le contraste entre la couleur de texte et la couleur de fond est-il suffisant ? Le menu est-il fonctionnel si CSS est indisponible ou non reconnu par les navigateurs ?Le menu est-il fonctionnel si JavaScript est indisponible ou non reconnu par les navigateurs ?Avez-vous testé l'accessibilité de la page via une synthèse vocale (VoiceOver, Nvda) ?Autre excellente pratique pour l'accessibilité : permettez la navigation au clavier en attribuant des styles CSS également lors de l'état :focus des liens de navigation (vous pouvez tester la navigation clavier à l'aide des touches tab ou maj + tab).Pour nos amis IE6 et IE7, qui ne reconnaissent pas la pseudo-classe :focus, nous emploierons :active qui, en raison d'un bug, déclenchera également les styles lors de la navigation au clavier sur ces anciens navigateurs.La navigation au clavier sera sans doute inutile sur mobile, mais redoutablement efficace sur écran de bureau :[id=navigation] a:hover, [id=navigation] a:focus, [id=navigation] a:active {background: #295155;}Les spécifications W3C d'accessibilité, WAI-ARIA, prévoient des régions nommées (landmarks) que les agents utilisateurs doivent savoir exploiter. Par exemple, la région "navigation", valeur de l'attribut HTML ARIA role, désigne la navigation prinicipale du document.Tous les agents utilisateurs récents reconnaissent ce landmark et traitent l'élément comme tel, cela vient en complément du sens apporté par l'élément HTML :role="navigation" id="navigation" class="nav-opened">L'exemple de ce menu de navigation vous l'a peut-être fait comprendre : l'amélioration progressive est un travail du quotidien et chaque détail peut avoir son importance.Ne cherchez pas absolument la perfection, car elle n'existe pas. Cet exemple est d'ailleurs forcément perfectible. Par contre, pensez avant tout à vos utilisateurs en priorité, et non à la technologie qui vous ferait plaisir : l'essentiel est que le contenu et les informations puissent toujours être véhiculées.revoir la démonstrationEt maintenant c'est à vous de jouer, qu'avez-vous prévu de faire pour faciliter la vie à vos visiteurs ?

No comments:

Post a Comment