Responsive design? Qu’est que c’est?

Si vous jetez un oeil sur la littérature liée à HTML5 / CCS 3, ou sur les thèmes WordPress les plus rescents, vous remarquerez certainement la présence d’un terme récurrent: « responsive ».  Nous allons donc voir ce que représente ce terme, et parler à cette occasion, de l’une des nouvelles fonctionnalités de CCS 3.

Le terme « responsive » pourrait se traduire par « adaptable ». En gros, un design est « responsive », s’il est capable de s’adapter à différents terminaux, disposant de tailles d’écran différentes.

Il est assez amusant de constater qu’il s’agit d’un retour à des pratiques qui avaient été un peu oubliées:

  1. Etape 1: Il y a 8 à 10 ans, avec l’adoption en masse des HTML4 et CCS, chacun essayait, avec plus ou moins de réussite, de transformer les designs basés sur des tables, en « autre chose ». La mode était alors aux designs fluides, et à l’accessibilité (l’inverse des designs utilisant des tables). Les grandes heures de sites comme Openweb.eu.org, et Alsacreations (qui sont toujours aussi intéressants à consulter),
  2. Etape 2: Puis, certainement fatigués par les heures nécessaires à la recherche du dernier hack CSS, capable de tourner sur n’importe quel navigateur, les designers se sont orientés vers les « grilles », outils magiques, permettant de construire très rapidement une structure de page robuste. Oublié les « faux columns », et les barres d’accessibilité. Les designs deviennent fixes: 750 pixels de large, puis plus tard 960 pixels, et plus pour certains. Sont oubliés les vieux PC/Mac, les netbooks, qui plafonnent à 800×600 ou 1024×728,
  3. Etape 3: la précédente étape va résister un certain temps à l’arrivée des terminaux mobiles (surtout l’iPhone en fait). Ces derniers proposant des « applications », pourquoi se fatiguer a construire un design adapté? Les sites les plus visités ont donc un site web, et une application. Oui mais voilà: les applications nécessitent d’être mises à jour, au même rythme que les sites eux-mêmes, elles augmentent la dépendance vis-à-vis de société comme Apple ou Google, et pour finir, les tablettes font une percée remarquée. Il ne s’agit donc plus de gérer deux résolutions, une pour les écrans classiques, et une pour les smartphones, mais de s’adapter à une multitude d’écrans de taille et de résolution différentes. Combinés à l’arrivée de CSS3, ces trois critères nous font revenir à l’étape 1: pour des sites pas trop compliqués, il faut mieux avoir un design adaptable, plutôt que de faire plusieurs fois le boulot.

L’utilisation d’internet depuis les Smartphones et les tablettes se développe énormement, et ne pas être accessible depuis ces terminaux peut être handicap. Sur se site: 95% des personnes le visitant disposent d’une résolution supérieure à 1024px (largeur). J’ai donc 5% de mes visiteurs qui utilisent des tablettes, netbooks ou Smartphones. Même si le pourcentage est faible, cela représente quelques dizaines de personnes, et rien ne dit que cette fréquentation ne pourrait pas être plus élevée, avec un design adapté.

Pour rendre, un design adaptable, il faut utiliser plusieurs techniques:

  • Transformer les largeurs fixes, en largeurs variables,
  • Utiliser une fonctionnalité de CSS, les medias queries,
  • Gérer la taille d’éléments comme les images (sujet que je n’aborderai pas dans cet article).

Designs fluides

Trois méthodes principales doivent être utilisées:

  • Utiliser des tailles relatives (en %) au lieu d’utiliser des pixels,
  • Utiliser des blocs « flottants », permettant un agencement « libre » des blocs entre eux,
  • Ne pas oublier l’alignement vertical, surtout la taille des polices qu’il faudra spécifier en % ou em, plutôt qu’en pixels.
Largeurs relatives

Prenons un exemple avec le framework 960.gs:

  • en mode normal, ce framework propose un design de 960 pixels sur 12 ou 16 colonnes,
  • avec 12 colonnes, les colonnes mesurent 60 pixels de large, avec des marges latérales de 10px: un élément d’une colonne occupera donc une largeur de 10+60+10 pixels, deux colonnes occuperont 10+2*(60+10)+10 pixels, …

Si l’on souhaite rendre la grille fluide :

  • Pour le conteneur, l’attribut width=960px devient min-width: 960px,
  • La largeur d’une colonne devient 60/960 = 6.25%, et les marges deviennent 10/960 = 1.041%,
  • Un élément de deux colonnes aura donc une largeur de 14.58% avec des marges toujours de 1.041%.

Tout va bien si vous n’avez pas de blocs imbriqués. En effet, les proportions indiquent une taille par rapport au bloc « parent ». Reprenons notre exemple: Nous avons une page dont la largeur initiale est de 960px. La section principale de cette page représente 64.58%  (620 px). Pour créer deux colonnes de largeur identique à l’intérieur de cette section, il faut utiliser la largeur de 620px, et non celle de 960px. Les colonnes feront donc 46.77% (290px) avec des marges de 10/620 = 1.61%.

La conception d’une grille fluide est donc assez fastidieuse …

Rythme vertical, taille des polices de caractères

Cet aspect est assez souvent oublié. Prenons deux exemples avec des frameworks CSS.
D’abord les styles typographiques du framework 960gs:

body { font: 13px/1.5 'Helvetica Neue', Arial, 'Liberation Sans', FreeSans, sans-serif; }
h1 { font-size: 25px;}
h2 { font-size: 23px;}
h3 { font-size: 21px;}
h4 { font-size: 19px;}

puis les mêmes styles avec le framework BluePrint CSS:

body {
    font-size: 75%;  /* (0.75 * 16px = 12px) */
    line-height: 1.5;
    font-family: "Helvetica Neue", Arial, Helvetica, sans-serif;
}
h1 { font-size: 3em; line-height: 1; margin-bottom: 0.5em; }
h2 { font-size: 2em; margin-bottom: 0.75em; }
h3 { font-size: 1.5em; line-height: 1; margin-bottom: 1em; }

Dans le premier cas, la taille du texte est fixée de façon définitive, quel que soit le terminal cible. Dans le second, la taille des polices sont calculées à partir de la taille par défaut utilisée par le navigateur (souvent 16px). La taille de toutes les balises est ensuite définie par rapport à la taille initiale (body).

Media-queries

Les media queries sont apparues avec HTML4 / CCS 2, et permettent de conditionner le chargement d’une feuille de style, au media cible. Il n’est pas rare de voir dans les entêtes de page HTML, ce type de ligne:

<link rel="stylesheet" type="text/css" href="screen.css" media="screen" title="Normal" />
<link rel="stylesheet" type="text/css" href="print.css" media="print" title="Normal" />

Ces directives pouvaient également être utilisées dans une feuille de style:

@media screen {
* { font-family: sans-serif }
}

La méthode était intéressante, à condition que le media cible (le terminal) soit clairement identifié (les types possibles étaient screen, print, handheld, ou projection, par exemple), avec les ambiguïtés possibles: un tablette est de type handheld ou screen?

La nouvelle spéficiation CSS3 étend les possibilités intiales, en apportant une plus grande précision dans les requêtes:

  • Les attributs peuvent être comparés à des valeurs chiffrées,
  • Ces critères peuvent être combinés

Exemples:

<link rel="stylesheet" media="screen and (min-width:500px)" href="example.css" />

ou encore, dans une feuille de styles:

@import url(color.css) screen and (color);
@media (min-width:500px) { … }
@media (orientation: portrait) { … }

Les critères sont assez nombreux, citons par exemple: color, aspect-ratio, height, width, orientation, resolution.

Prenons un exemple, avec un menu de ce type de menu

Menu affiché pour un écran de grande taille

qui s’obtient avec un code HTML de ce type,

<nav id="main">
  <ul>
    <li class="home"><a title="Accueil du blog" href="#">Accueil</a></li>
    <li class="perso"><a href="#">Perso</a></li>
    <li class="photo"><a href="#">Photo</a></li>
    <li class="techno"><a href="h#">Techno</a></li>
    <li  class="dev"><a href="#">Développements</a></li>
  </ul>
</nav>

accompagné du code CSS suivant:

    nav#main li { float: left; }
    nav#main a {
        text-align: center;
        display: block;
        color: lightgrey;
        height: 25px;
        width: 140px;
        padding-top: 80px;
    }
    nav#main li.home a { background: #333333 url('img/button_perso.jpg') no-repeat left top;}
    nav#main li.home a:hover { background: #333333 url('img/button_perso_hover.jpg') no-repeat left top;}
    nav#main li.perso a { ... }
    nav#main li.perso a:hover { ... }

Pour résumer, nous utilisons la propriété float sur les balises LI, et une image de fond avec les balises A.

Ce type de design est assez sympa, mais il a un principal inconvénient, il prend de la place: chaque menu occupe une surface d’environ 115*140. Certes les différents éléments s’agencent correctement en fonction de la taille de l’écran, mais l’ergonomie pourrait être optimisée.

Nous allons pour cela utiliser deux médias queries.

  • Comme le menu fait 5*140=700 pixels de large, nous allons considérer qu’il faut réduire cette largeur, dès que la résolution descend en dessous de cette limite,
  • Lorsque la résolution devient vraiment réduite (moins de 500 pixels), alors nous passerons en mode vertical.

Sans toucher au code HTML, nous allons modifier le code CSS en y ajoutant les lignes suivantes:

@media (max-width: 750px) {
    nav#main-nav  ul { margin-left: 0; }
    nav#main-nav a {
        text-align: left;
        display: block;
        color: lightgrey;
        padding: 0.2em 2.5em;
        border: 1px solid #666;
        text-decoration: none;
        padding-top: 0.5em;
        height: 2em;
        width: 70px;
    }
    nav#main-nav li.home a,
    nav#main-nav li.home a:hover {
        background: url('img/ ... .png') no-repeat 5px center ;
    }
    nav#main-nav li.perso a,
    nav#main-nav li.perso a:hover { ... }
 
    nav#main-nav a:hover {
        border: 1px solid white;
        background-color: #666;
        color: white;
        text-decoration: underline;
    }
}

puis

@media (max-width: 500px) {
 
    nav#main-nav  ul { margin-left: 0; }
    nav#main-nav  li { float: none; }
    nav#main-nav a {
        text-align: left;
        display: block;
        color: lightgrey;
        padding: 0.2em 2.5em;
        border: 1px solid #666;
        text-decoration: none;
        padding-top: 0.5em;
        height: 2em;
        width: 70px;
    }
    nav#main-nav li.home a,
    nav#main-nav li.home a:hover {
        background: url('img/ ....png') no-repeat 5px center ;
    }
    nav#main-nav li.menu-perso a,
    nav#main-nav li.menu-perso a:hover { ... }
 
    nav#main-nav a:hover {
        border: 1px solid white;
        background-color: #666;
        color: white;
        text-decoration: underline;
    }
}

Explications rapides:

  • lorsque la largeur disponible devient inférieure à 750pixels, nous modifions les boutons de façon à les rendre moins larges. Par rapport aux styles initiaux, nous changeons l’image de fond, et réduisons la taille des balises LI
  • lorsque la largeur disponible descend en dessous de 500 pixels, nous reprenons les styles précédents, en enlevant la propriété float de la balise LI.

Les résultats sont vraiment « impressionnants », compte-tenu de la simplicité de la solution:

Menu affiché pour un écran de grande taille
Menu affiché pour des largeurs d'écran comprises entre 500 et 750px.
Menu affiché pour des largeurs d'écran inférieures à 500px

Plutôt que d’intégrer le code directement dans la feuille de styles, il est possible d’utiliser @import, qui permet de charger les styles en fonction du besoin.

Compatibilité

Cette fonctionnalité n’est malheureusement pas disponible sur les versions d’Internet Explorer inférieure à 9.

Certains frameworks, comme 960 Grid System,  proposent des scripts émulant le comportement des medias-queries.

Scott Jehl a développé un script Javascript plus générique (disponible ICI). Le script respond.min.js doit obligatoirement être placé dans la section HEAD de la page.

Les quelques tests effectués avec Internet Explorer 7, ne sont pas tous probants, et montrent que la solution n’est pas fiable à 100%.

Je n’ai pas beaucoup creusé cette question, pour moi, l’impact est limité, puisqu’ Internet Explorer ne fonctionne que sur des ordinateurs disposant d’un écran confortable (netbooks, portables, ou PCs). J’irais plus loin si Windows Mobile devient plus populaire qu’il ne l’est actuellement.

Conclusion

Au premier abord, concevoir un thème qui s’adapte à la taille de l’écran cible ne semble pas aisé. Comme nous venons de le voir dans cet article, avec la fonction Media Query, et un design fluide, les styles CSS nous offrent des outils extrêmement puissants, pour peu qu’ils soient supportés par les navigateurs (encore Internet Explorer).

Il est clair, cependant que tout doit être pensé dès le départ: il ne suffit pas d’avoir un design fluide, pour être lisible partout. L’affichage des images peut poser problème: Il faudra peut-être prévoir d’en stocker plusieurs versions de différentes tailles, par exemple.

Je pense également qu’il ne faut pas pousser trop loin la logique, pour deux raisons:

  • Certes, un site qui finit par ressembler à une application lorsqu’il est visualisé sur un smartphone, est ergonomiquement réussi, mais la résolution de ces terminaux augmente régulièrement: l’iPhone est passé de 480 pixels en version 3GS, à 960 pixels avec sa version 4, et ne parlons pas de la résolution du Galaxy S2 qui atteint 1280 pixels!
  • La fonction zoom des navigateurs permet une visualisation relativement confortable de beaucoup de sites. Même si la largeur des designs actuels se rapproche plutôt de 960 pixels, cette largeur est très souvent occupée par une sidebar de 180 ou 240pixels. La largeur « utile » tombe à moins de 800 pixels, ce qui devient lisible/gérable sur un téléphone comme l’iPhone 4 ou un Galaxy S, et encore plus sur une tablette.

Vous venez de découvrir à l’occasion de cet article, une partie de ce qui pourrait être le futur design de ce blog.

Références

Partager cet article