Amélioration responsive

L'amélioration progressive n'est pas une technologie, c'est une façon de penser. Jeremy Keith montre ici comment cette idée est non seulement respectueuse des utilisateurs mais également incroyablement libératrice de créativité.

Par

24 Ways marche fort depuis 10 ans. C’est une éternité à l’échelle d’internet ! Pensez à tous les changements intervenus depuis cette époque : la montée en puissance d’Ajax, l’explosion des terminaux mobiles, le paysage de l’outillage front-end.

Les outils et les technologies vont et viennent, mais il est une chose qui demeure une constante pour moi : l’amélioration progressive.

L’amélioration progressive n’est pas une technologie. C’est une façon de penser. Plutôt que de penser aux détails de la présentation finale d’un site, l’amélioration progressive vous encourage à réfléchir au sens fondamental de ce que le site propose. Autrement dit, au lieu de penser un site web dans sa configuration idéale dans un navigateur moderne et sur un écran large, l’amélioration progressive vous permet de penser aux fonctionnalités essentielles d’une façon plus abstraite.

Une fois que vous avez défini les fonctionnalités essentielles — ajouter un item à votre liste d’achats, envoyer un message, partager une photo — vous pouvez mettre en oeuvre cette fonctionnalité de la manière la plus simple, ce qui signifie généralement commencer avec ce bon vieux HTML. Les liens et les formulaires sont souvent nécessaires. Puis, une fois cette fonctionnalité mise en oeuvre de manière basique, vous pouvez commencer à l’améliorer afin d’offrir une meilleure expérience aux utilisateurs de navigateurs modernes.

L’avantage de cette méthode de travail n’est pas seulement qu’elle permet à notre site de fonctionner avec des navigateurs anciens (bien que d’une manière rudimentaire). Il est aussi d’assurer que si quoi que ce soit se passe mal dans un navigateur moderne, cela n’aura pas de conséquence catastrophique.

C’est un malentendu assez courant que de croire que l’amélioration progressive signifie passer son temps à s’occuper des navigateurs anciens, alors que c’est tout l’inverse qui est vrai. Mettre en place les fonctionnalités de base ne prend pas beaucoup de temps, et une fois que c’est fait, vous êtes libre de consacrer le temps que vous voulez à expérimenter les dernières technologies, avec la certitude que même si leur compatibilité n’est pas universelle il n’y aura pas de problème : vous avez déjà votre solution de repli.

Pour comprendre le développement web, il est essentiel de prendre conscience qu’il n’existe pas une interface finale — il pourrait y en avoir beaucoup, et assez différentes, en fonction des propriétés et des capacités d’un agent utilisateur à un moment donné. Et c’est très bien ainsi. Les sites web n’ont pas besoin d’être identiques dans tous les navigateurs.

C’est une idée qui, une fois qu’on l’a acceptée, est incroyablement libératrice. Au lieu de passer son temps à essayer de rendre un site semblable d’un navigateur à l’autre, dans un paysage perpétuellement changeant, on peut l’utiliser à s’assurer que les fonctionnalités essentielles sont disponibles pour tous et se concentrer sur l’amélioration de l’expérience avec les navigateurs les plus modernes.

Permettez-moi de démontrer cette idée avec un exemple simple : la navigation.

Étape 1 - Fonctionnalités de base

Disons que nous avons un site assez simple, qui traite des douze jours précédant Noël avec une page pour chacun. La fonctionnalité basique est claire :

  1. Pouvoir lire tout ce qui concerne une journée quelconque
  2. Pouvoir naviguer d’un jour à l’autre.

La première est réalisée en balisant le texte avec des titres, des paragraphes et les éléments HTML habituels. La seconde est satisfaite à l’aide de bons vieux hyperliens.

Quel est le meilleur endroit pour positionner cette liste de navigation ? Personnellement je suis un adepte du pattern jump-to-footer qui met en avant le contenu d’abord, la navigation ensuite. En haut de page, on a un lien avec un attribut href pointant vers l’identificateur de fragment pour la navigation.

<body>
      <main role="main" id="top">
        <a href="#menu" class="control">Menu</a>
        ...
      </main>
      <nav role="navigation" id="menu">
        ...
        <a href="#top" class="control">Dismiss</a>
      </nav>
</body>

Voir le pattern footer-anchor en action.

Ce n’est rien de plus qu’un hyperlien et par conséquent cela fonctionne dans tous les navigateurs depuis la naissance du web. Les navigateurs ont eu pour première fonction de suivre les liens (d’où leur nom).

Étape 2 - La mise en page comme amélioration

Le pattern footer-anchor (pied de page - ancre) est une solution élégante et astucieuse pour les petits écrans, comme ceux des mobiles. Une fois qu’on dispose d’un écran plus large, je peux utiliser la magie de CSS pour repositionner la navigation au-dessus du contenu. Je pourrais utiliser position: absolute, flexbox ou, comme ici, display: table.

@media all and (min-width: 35em) {
      .control {
        display: none;
      }
      body {
        display: table;
      }
      [role="navigation"] {
        display: table-caption;
        columns: 6 15em;
      }
}

Voir les styles pour les écrans plus larges en action.

Étape 3 - Améliorez !

Très bien. Arrivé à ce point, je fournis les fonctionnalités de base à tous et j’ai un style responsif pour les écrans larges. Je pourrais m’arrêter ici, mais le véritable avantage de l’amélioration progressive est que je n’ai pas besoin de m’arrêter. À partir de maintenant, je peux me lancer dans les expérimentations les plus folles, ajouter toutes sortes d’améliorations pour les navigateurs modernes sans avoir à m’inquiéter de la solution de repli (fallback) puisqu’elle est déjà en place.

Ce que j’aimerais proposer, c’est un pattern off-canvas pour les terminaux à petit écran. Voici mon plan :

  1. Positionner la navigation sous le contenu principal
  2. Écouter l’activation des liens .control et intercepter cette action
  3. Lorsque ces liens sont activés, basculer la classe .active sur le body
  4. Si la classe .active existe, faire glisser le contenu vers l’extérieur pour révéler la navigation.

Voici le CSS permettant de positionner le contenu et la navigation :

@media all and (max-width: 35em) {
      [role="main"] {
        transition: all .25s;
        width: 100%;
        position: absolute;
        z-index: 2;
        top: 0;
        right: 0;
      }
      [role="navigation"] {
        width: 75%;
        position: absolute;
        z-index: 1;
        top: 0;
        right: 0;
      }
      .active [role="main"] {
        transform: translateX(-75%);
      }
}

Dans mon JavaScript, je vais écouter les clics qui se produisent sur les liens .control et basculer (toggle) la classe .active sur le body en fonction :

(function (win, doc) {
      'use strict';
      var linkclass = 'control',
        activeclass = 'active',
        toggleClassName = function (element, toggleClass) {
              var reg = new RegExp('(s|^)' + toggleClass + '(s|$)');
              if (!element.className.match(reg)) {
                element.className += ' ' + toggleClass;
              } else {
                element.className = element.className.replace(reg, '');
              }
        },
        navListener = function (ev) {
              ev = ev || win.event;
              var target = ev.target || ev.srcElement;
              if (target.className.indexOf(linkclass) !== -1) {
                ev.preventDefault();
                toggleClassName(doc.body, activeclass);
              }
        };
      doc.addEventListener('click', navListener, false);
}(this, this.document));

Tout est prêt, n’est-ce pas ? Pas si vite !

Ça le fait

Je suis parti de l’hypothèse que addEventListener serait disponible dans mon JavaScript. Ce n’est pas une hypothèse prudente. Parce que JavaScript — contrairement à HTML et CSS — n’est pas tolérant à l’égard des fautes. Si vous utilisez un élément HTML ou un attribut que le navigateur ne comprend pas ou si vous utilisez un sélecteur, une propriété ou une valeur CSS que le navigateur ne comprend pas, ce n’est pas un problème, le navigateur ignore ce qu’il ne comprend pas, il n’enverra pas d’erreur et continuera de parser le fichier.

Il n’en va pas de même avec JavaScript. S’il y a une erreur dans votre JavaScript ou si vous utilisez une méthode ou une propriété JS que votre navigateur ne reconnaît pas, il enverra une erreur et il s’arrêtera. C’est pourquoi il est important de tester les fonctionnalités avant de les utiliser dans JavaScript. C’est aussi la raison pour laquelle il n’est pas prudent de compter sur JavaScript dans les fonctionnalités de base.

Dans mon cas, je dois tester l’existence de addEventListener :

(function (win, doc) {
      if (!win.addEventListener) {
        return;
      }
      ...
}(this, this.document));

Les petits gars de la BBC appellent ce genre de test “ça le fait” (cutting the mustard). Si un navigateur passe le test il bénéficie de l’amélioration. Sinon... eh bien non, et c’est très bien ainsi, rappelez-vous, les sites web n’ont pas besoin d’être identiques d’un navigateur à l’autre !

Je veux m’assurer que les styles off-canvas ne s’appliqueront qu’aux navigateurs qui ont passé victorieusement le test. Je vais utiliser JavaScript pour ajouter une classe .cutsthemustard au document :

(function (win, doc) {
      if (!win.addEventListener) {
        return;
      }
      ...
      var enhanceclass = 'cutsthemustard';
      doc.documentElement.className += ' ' + enhanceclass;
}(this, this.document));

Et maintenant je peux utiliser ce nom de classe pour ajuster mon CSS :

@media all and (max-width: 35em) {
      .cutsthemustard [role="main"] {
        transition: all .25s;
        width: 100%;
        position: absolute;
        z-index: 2;
        top: 0;
        right: 0;
      }
      .cutsthemustard [role="navigation"] {
        width: 75%;
        position: absolute;
        z-index: 1;
        top: 0;
        right: 0;
      }
      .cutsthemustard .active [role="main"] {
        transform: translateX(-75%);
      }
}

Voir la navigation off-canvas améliorée qui le fait. N’oubliez pas que cela ne s’applique qu’aux écrans de taille réduite, donc pour voir l’effet il faudra sans doute redimensionner votre fenêtre navigateur.

Tout améliorer !

C’était un exemple relativement simple, mais il illustre la pensée qui est derrière l’amélioration progressive : une fois que vous offrez les fonctionnalités essentielles à chacun, vous êtes libre de délirer avec toutes les dernières améliorations des navigateurs modernes.

L’amélioration progressive ne signifie pas que vous devez offrir à tous les mêmes fonctionnalités — c’est même l’inverse. C’est pourquoi il est fondamental de bien discerner dès le départ quelles sont les fonctionnalités essentielles et de vous assurer qu’elles peuvent être fournies par la technologie la plus basique. Mais à partir de là, vous êtes libre d’ajouter d’autres fonctionnalités qui ne sont pas essentielles à la mission. Récompensez les navigateurs les plus avancés en leur offrant plus de ces fonctionnalités, comme les animations CSS, la géolocalisation JavaScript, les nouveaux types d’input en HTML.

Comme je le disais en commençant, l’amélioration progressive n’est pas une technologie, c’est une façon de penser. Une fois que vous pensez de cette manière, vous êtes prêt pour ce que les 10 prochaines années nous réservent.


Intéressé par l’amélioration progressive ? Sur la Cascade, retrouvez la liste des articles les plus importants, traduits en français.


original paru le dans 24 Ways.

Sur l’auteur : est développeur web et auteur, responsable recherche et développement chez Clearleft, il vit à Brighton en Angleterre. Il est l’auteur notamment de HTML5 pour les webdesigners. On peut le suivre sur Google+ et Twitter.

Traduit avec l’aimable autorisation de 24 Ways et de l’auteur.
Copyright 24 Ways © 2014.