VI. TD5 - Responsive design▲
VI-A. Introduction▲
Les smartphones, les tablettes et tous les appareils de la mobilité demandent de repenser le web d'aujourd'hui. Concevoir un site ou une application Web s'adressant à tous ces médias n'est pas une tâche triviale. Voici un aperçu des nombreuses solutions existantes :
- une solution en pur CSS. En effet, le CSS est le langage de base pour la mise en page des pages Web. Il est donc en constante évolution (CSS3 en cours d'élaboration) pour s'adapter aux nouveaux besoins ;
- coder deux sites en HTML/CSS : un pour les ordinateurs et un pour les smartphones (et un pour les tablettes ? et un pour les smartwatch ?). Exemple lemonde.fr et mobile.lemonde.fr ;
- des applications natives pour chaque système (Android, iOS, Windows Phone…) ;
- l'utilisation de la puissance de JavaScript pour faire des mises en page adaptatives ;
- faire le site en Flash (très mauvaise idée, car il n'est plus supporté sur Android ni iOS).
Plus pour nous positionner dans cette jungle que par purisme, nous prendrons deux hypothèses de départ :
- « Il n'y a pas besoin d'applications pour cela ! » : pas besoin de faire du natif Android ou iOS ;
- « Il n'y a pas besoin de faire deux sites web pour cela ! » : on s'interdit de faire un site Web pour mobile et un pour ordinateur.
Nous adopterons dans ce TD une approche itérative, en rajoutant au fur et à mesure des contraintes pour arriver à ce qui se fait aujourd'hui dans le responsive design.
VI-B. CSS2▲
Certaines propriétés n'ont pas attendu ni les nouveaux médias ni le CSS3 pour s'imposer aux développeurs. Elles prenaient déjà tout leur sens sur des sites particulièrement fournis et/ou sur des petits écrans 15 pouces.
VI-B-1. Les pourcentages « % »▲
On peut commencer par exprimer toutes les tailles en relatif, en prenant comme référence la largeur de l'écran. C'est ce que nous avons déjà fait en utilisant des dimensions en %.
Exercice 1
- Donnez à <body> la width de 100%. Donnez à la propriété margin la valeur auto si ce n'est pas le cas.
- Enlevez au besoin la marge de gauche de 10% sur le <aside> et changez les dimensions relatives de <article> et <aside> Ã respectivement 67% et 33%.
Note : si adapter les largeurs en pourcentage marche bien, ce n'est pas le cas des hauteurs. Cela est dû au fait que la largeur de la page est connue (c'est la largeur de la fenêtre d'affichage du navigateur) mais sa hauteur ne l'est pas encore… (puisque la page n'est pas encore affichée et que la hauteur va dépendre de la quantité de contenu). Autrement dit, la hauteur de la zone du navigateur où s'affiche la page (viewport height) n'est pas forcément la hauteur de la page(2) (et c'est lié à la présence d'un ascenseur à droite pour descendre dans la page).
VI-B-2. max-width et min-width▲
Les règles précédentes permettent d'avoir un rapport homogène, mais pas un rendu optimal :
- sur de petits écrans d'ordinateur, des éléments ne peuvent pas être correctement affichés (des images, des colonnes…) ;
- sur de très grands écrans, le texte devient illisible : les yeux fatiguent à cause des lignes trop longues.
Pour contraindre les dimensions maximales et minimales, nous utiliserons max-width, max-height, min-width et min-height, qui prennent le même type de valeur que width et height.
Exercice 2
VI-B-3. Overconstraint▲
Mais que se passe-t-il quand on mélange min-width et des tailles en pourcentage ? Prenons l'exemple suivant
qui s'affiche comme suit
Exercice 3
Remarquez en changeant la largeur de votre fenêtre (ou en zoomant) que :
- Les deux <div> prennent toute la largeur quand <body> a une largeur inférieure à 800px (donc le premier <div> a une largeur de moins de 400px) ;
- Mais quand la largeur de <body> est supérieure à 800px, alors les deux <div> ne remplissent plus toute la largeur de <body>.
Nous allons utiliser display:
flex pour mieux mélanger les tailles relatives et les contraintes min-width/max-width. Nous avions déjà vu les règles de la colonne de gauche de cette super page sur FlexBox : c'était celles qui s'appliquaient au parent. Nous allons maintenant nous pencher sur la colonne de droite qui s'applique aux balises enfants. Regardez particulièrement les propriétés flex-shrink (valeur par défaut 1), flex-grow (valeur par défaut 0). Pour l'instant, nous ne toucherons pas à flex-basis (qui gardera donc son comportement par défaut auto).
Exercice 4
- Lisez la section sur flex-shrink et flex-grow dans le guide de FlexBox ou toute autre page Web. N'hésitez pas à parler de votre compréhension avec votre professeur.
-
Donnons un exemple d'utilisation de flex-grow. Votre boulot est de vérifier que vous comprenez son fonctionnement.
Nous pouvons désormais résoudre le problème précédent avec flex-grow:
1;.Sélectionnezqui s'affiche comme suit
Maintenant que la largeur de <body> est supérieure à 800px, alors le second <div> voit sa largeur augmenter grâce à flex-grow
:
1;. Donc les deux <div> remplissent toujours la largeur de <body>. -
Changez les largeurs de <article> et <aside> pour qu'elles soient par défaut de 300px et 200px. Mettez les propriétés flex-shrink et flex-grow pour ces deux éléments à 0.
Bougez la largeur de la page. Est-ce que les largeurs de <article> et <aside> changent ? -
Nous souhaitons que quand l'écran est trop large, l'espace restant soit réparti entre <article> et <aside> de telle sorte que l'espace gagné par <article> soit 3 fois plus grand que celui gagné par <aside>.
Quelle propriété CSS devez-vous utiliser pour avoir ce comportement ? Implémentez ce comportement. -
Pour vérifier que vous avez bien répondu à la question précédente, redimensionnez la fenêtre du navigateur pour que la largeur de <body> soit de 620px.
Quelles devraient être selon vous les largeurs de <article> et <aside> ? Inspectez maintenant les largeurs de <article> et <aside> pour vérifier votre calcul. - Nous souhaitons que quand l'écran est trop petit, <article> diminuera de deux tiers de la largeur à supprimer et <aside> diminuera du reste.
Quelle propriété CSS devez-vous utiliser pour avoir ce comportement ? Implémentez ce comportement.
VI-B-4. Problèmes plus complexes▲
Il arrive un moment où diminuer encore la taille n'a plus de sens. Il faut prendre des mesures draconiennes, par exemple passer <aside> sous <article> ou carrément supprimer <aside>.
Les règles CSS déjà vues en TD ne permettent pas de coder ce genre de comportement. Il nous faut une façon d'écrire du CSS qui ne sera valide que dans des cas précis. Nous verrons dans la prochaine section comment cela est possible en CSS3.
VI-C. Votre site de Chuck Norris sur mobile▲
VI-C-1. Les outils pour travailler ?▲
Jusqu'ici on pouvait considérer que tous les outils de développement d'Internet Explorer/Firefox/Chrome étaient égaux. En fait celui de Chrome était déjà un peu meilleur :
- autocomplétion des règles CSS ajoutées dynamiquement ;
- liste déroulante des valeurs possibles des champs ;
- plus rapide, plus stable (un processus par onglet)Â ;
- etc.
En tout cas, pour le reponsive design il n'y a pas photo : Chrome (ou son pendant libre Chromium) est vraiment votre « best-friend-ever ».
VI-C-2. Que fait mon navigateur Web sur téléphone par défaut pour un site ?▲
Comment peut-on rendre un site Internet compatible mobile à moindre coût ?
Voici l'algorithme (simplifié) opérant par défaut :
- générer le site sur une taille d'écran virtuel, disons d'une largeur de 980px ;
- faire un zoom arrière de manière à faire rentrer le site dans l'écran du smartphone ; (oui, cela fait de petits éléments) ;
- supposer que l'utilisateur connaît le pinch to zoom pour naviguer dans le site :
Et ça marche ! De fait, c'est ce que font par défaut les smartphones quand ils tombent sur un site non responsive.
Exercice 5
- Dans les outils développeurs (F12) de Chrome/Chromium, passez dans le device mode « Samsumg Galaxy S5 » sous Chrome/Chromium et rechargez votre page. Constatez que le site s'affiche en tout petit.
- Vérifiez que la taille du <body> est de 980px, ce qui signifie que l'algorithme précédent a été utilisé pour l'affichage.
Remarquez aussi que la largeur de l'affichage est de 360px, ce qui signifie qu'un zoom arrière est effectué.
Même si cela marche, on ne peut pas dire que cela soit optimal. L'utilisateur mobile n'a pas la même attente que l'utilisateur sur ordinateur, il veut avoir accès rapidement aux informations essentielles, sans fioritures. On imagine que sur une smart watch par exemple un site comme Météo France serait largement plus dépouillé (sur une smartwatch elle afficherait un nuage ou un soleil et la température par exemple).
Typiquement nous voulons enlever des parties entières du site suivant la taille de l'écran.
La première chose à faire est donc de demander aux navigateurs de ne plus faire l'algorithme précédent (puisqu'on va le gérer nous-même) dans la balise <head> :
<meta name
=
"viewport"
content
=
"width=device-width, initial-scale=1"
>
Exercice 6
- Ajoutez cette instruction au site de Chuck Norris et visualisez avec Chrome en choisissant un smartphone. Inspectez la largeur de <body>. Que constatez-vous ?
Vous devez constater que l'algorithme précédent ne s'applique plus. En gros le navigateur n'essaie plus d'être intelligent : il vous laisse prendre le relai.
VI-D. La solution technique CSS3Â : les media queries▲
Les media queries sont un jeu d'options ajoutées à la norme CSS3 et qui permettent de définir des règles CSS qui ne s'appliqueront que sous certaines conditions spécifiques.
Il existe deux manières différentes de faire appel à une media query :
-
soit vous souhaitez un fichier CSS spécifique en entier, mais uniquement dans certaines conditions. Alors il faut ajouter à l'en-tête <head> de la page web une déclaration de fichier CSS standard, à laquelle on ajoute l'attribut media et une condition spécifique.
Sélectionnez<link
rel
=
"stylesheet"
media
=
"condition"
href
=
"mon_css_special.css"
/>
N'oubliez pas que le dernier CSS chargé prend le pas sur les précédents. Pensez donc à toujours déclarer vos media queries en dernier, sinon elles seront systématiquement écrasées par votre CSS « standard » ;
- soit vous souhaitez que juste certaines règles s'appliquent sous certaines conditions. Alors vous englobez vos règles avec la syntaxe suivante :
2.
3.
4.
@media
(
ma_condition)
{
div {
background-color:
white
;}
...
}
Une media query fonctionne de la manière suivante : la condition est évaluée et retourne une valeur « vrai » ou « faux ». Si la valeur est vraie, le fichier CSS/la règle CSS (selon la méthode employée) est appliquée.
Chaque condition est formée à partir d'une ou plusieurs conditions de base. Parmi l'ensemble des conditions possibles, nous allons nous intéresser particulièrement aux suivantes :
-
min-width, max-width, min-height et max-height : permettent de renseigner une dimension minimale/maximale à remplir pour que la condition soit vraie. Par exemple,
Sélectionnez1.
2.
3.@media
(
min-width:
100
px)
{
div{
background-color:
white
;}
}
- orientation : prend les valeurs landscape (écran horizontal) ou portrait (écran vertical)
Les conditions de base peuvent être combinées ensemble pour former des conditions complexes en utilisant les opérateurs logiques :
- « and » (ET) : les deux conditions de base doivent être vraies pour que la condition soit vraie ;
- « , » (OU) : au moins l'une des conditions de base doit être vraie pour que la condition soit vraie ;
- « not » (NON) : la condition de base qui suit le not doit être fausse pour que la condition soit vraie.
Exemple : la règle (
min-width:
500
px)
and (
min-height:
800
px)
n'est vraie que si la largeur de l'affichage est supérieure (ou égale) à 500px et la hauteur supérieure à 800px.
Exercice 7
- Allez sur le site Bootstrap et constatez qu'il y a deux largeurs pour lesquelles la mise en page change.
- Utilisez le device mode pour afficher les media queries (cliquer sur les trois points verticaux du device mode pour afficher ces media queries).
- Que se passe-t-il visuellement dans le menu lorsque vous redimensionnez la fenêtre autour du point de rupture situé à 768px ?
VI-D-1. Les points de rupture▲
Afin d'organiser nos media queries, on utilise en général trois ou quatre valeurs de largeur d'écran, par exemple :
- 480px (Smartphone)Â ;
- 768px (Tablette)Â ;
- 992px (écran d'ordinateur « Standard ») ;
- 1200px (écran d'ordinateur « Large »).
Exercice 8
- En dessous de 768px ne plus afficher la table de comparaison (de toute façon s'il ne doit rester qu'un seul, ce sera Chuck Norris).
- En dessous de 480px faire en sorte qu'<aside> et <article> soient en colonne et plus en ligne.
- (Optionnel) Sur une smartwatch (width 168px), n'affichez que les citations de Chuck Norris contenues dans le <aside>.
VI-D-2. Mettez-moi un burger au menu !▲
Quand la taille de l'écran est limitée, une bonne pratique en responsive design est de changer l'affichage du menu pour un bouton burger :
Lorsque l'on cliquera dessus, le menu apparaîtra. Cela permet de ne pas perdre de place sur la page lorsque le menu est fermé. Pour fixer les idées, nous voulons un menu qui apparaît latéralement à la manière des exemples suivants :
(Notez au passage que codepen.io est un très bon outil pour découvrir de nouvelles techniques !)
Exercice 9
Nous allons coder un deuxième menu, identique au premier dans son contenu, mais avec une mise en page différente. Nous allons afficher l'un ou l'autre des menus en fonction de la taille de l'écran.
- Ajoutez un <div> de classe burger contenant l'image de burger (largeur 50px) juste avant le menu <nav>.
- À partir du point de rupture ‘Smartphone', faites disparaître l'ancien menu et faites apparaître le <div
class
=
"burger"
>
à droite de la page (à la place du menu). -
Implémentez le deuxième menu avec les caractéristiques suivantes :
- son contenu est
2.
3.
4.
5.
6.
7.
8.
9.
<div class
=
"burger"
>
<img src
=
"images/burger.png"
alt
=
"burger"
width
=
"50px"
>
<div id
=
"menu2"
>
<div><a href
=
"./index.html"
>
Accueil</a></div>
<div><a href
=
"./facts.html"
>
Facts</a></div>
<div><a href
=
"./news.html"
>
Actualités</a></div>
<div><a href
=
"./contact.html"
>
Contact</a></div>
</div>
</div>
- il se positionne par rapport à la fenêtre d'affichage (quelle valeur de position faut-il mettre ?), tout en haut à droite ;
- il occupe 80 % de la largeur de la fenêtre d'affichage et 100 % de sa hauteur (cherchez sur le Web les unités de mesure vh et vw(3)) ;
- il est visuellement au-dessus des autres éléments du site (cherchez sur le Web la propriété z-index) ;
- les sous-menus sont disposés verticalement.
Note : le hover sur les sous-menus n'a pas de sens sur téléphone portable. Il faudra gérer le clic avec du JS. La bonne solution est… suspense, vous la verrez en 2e année.
VI-D-3. La mobilité en général▲
Les contraintes liées à la mobilité ne se limitent pas au responsive design. Pour vous donner une idée plus complète, voici d'autres exemples de contraintes fortes qui viennent s'ajouter :
- débit du réseau ;
- faible capacité du média (processeur, mémoire vive…) ;
- mode offline (on peut passer sous un pont… il faut prévoir pour le cas échéant un cache local qui stocke les opérations courantes, afin de les consommer lorsque le réseau revient) ;
- changement de paradigme de l'interface homme-machine (mouse over, menu déroulant…).
VII. Note de la rédaction de Developpez.com▲
Nous tenons à remercier Romain Lebreton qui nous a aimablement autorisés à publier son tutoriel. Nous remercions également Winjerome pour la mise au gabarit et Claude Leloup pour la relecture orthographique.