ESTHÉTIQUE
SIMPLICITÉ
EFFICACITÉ

Aneartiste sur deviantartAneartiste sur twitter Aneartiste sur scoop-it

Media-Queries, une affaire d'échelles

C'est quoi cet écran ?

Aux débuts de la conception Web, les pages étaient construites pour cibler une taille d'écran particulière, généralement proche du format SVGA qui offrait alors une définition de 800x600 pixels. Lorsque le web mobile a commencé à devenir une réalité avec les premiers téléphones à fonctions, certains sites proposèrent une version mobile adaptée, avec une URL différente (m.example.com ou example.mobi) mais cela nécessitait une double maintenance de la part des développeurs. À mesure que les tailles d'écran disponibles se multipliaient, certaines personnes comme Cameron Adams, ont initiés des méthodes de design pouvant s'adapter à ce nouveau paradigme. Le terme de responsive design (RWD) fut inventé par Ethan Marcotte en 2010, et combine trois techniques. La première consiste à utiliser des mesures en pourcentages (% ou em) plutôt qu’en pixel. l'em est une unité de mesure relative. Elle n’a pas une valeur absolue comme les pixels, les inchs ou les points. Elle est basée sur la taille de la police de l’élément parent. Par exemple, 1.5em est égal à 150% de la taille de la police de l’élément parent. Quant aux deux autres, il s'agit du design réactif, utilisant des frameworks adaptatif (skeleton, bootstrap...), et du design adapté à des largeurs précises via les medias queries.

un menu web en responsive-design,Capture d'écranCapture d'écran

« Selon le vent, la voile. »
—Proverbe


Pixel-Ratio et Pixel-CSS

Ces dernières permet de cibler du CSS spécifiquement à une taille d’écran. Par exemple, le code suivant appliquera du CSS uniquement aux écrans plus petits que 1024 pixels de large :
@media screen and (max-width:1024px) {
/* CSS ici */
}
Sur les mobiles, bien que les écrans soient beaucoup plus petits, les définitions des écrans sont proches de celles qu’on trouve sur les ordinateurs. Les écrans Full-HD affichent par exemple un écran d’une définition de 1920×1080 pixels, dans un rectangle de 12 cm de diagonales (5 pouces). Un ordinateur avec la même définition affichera la même chose dans un rectangle de près de 43 cm (17 pouces). À l’usage, la différence est à la mesure de l'illisibilité. Sans media-queries, la page web s’affichera de la même façon sur un téléphone que sur un ordinateur, mais en beaucoup plus petit ; peu fonctionnel même s'il est toujours possible de zoomer. Il importe donc de notifier au navigateur qu'il ne doit pas utiliser le même mode d’affichage qu’un écran d’ordinateur. Si par exemple, au lieu d’utiliser 14 pixels pour afficher la lettre « M », il en utilise 28, on dira que le pixel-ratio est de 2. En spécifiant un pixel-ratio de 2 le navigateur affichera la page comme si la définition de l’image était deux fois plus petite : de 1920×1080 pixels, on passe alors à 960×540 pixels.

« Ne pouvant régler les événements, je me règle moi-même. »
—Montaigne

Le DPR ou Pixel-Ratio se défini comme étant le nombre de pixels physiques composant un pixel CSS. Cependant, une valeur DPR de 2 ne signifie pas qu'1 pixel CSS est égal à 2 pixels physiques. En pratique, 1 pixel CSS correspondra à un carré constitué de 2 pixels de côté (soit 2 pixels en largeur x 2 en hauteur = 4 pixels). S’il est possible de spécifier explicitement la valeur du pixel-ratio dans le HTML ou le CSS, il est souvent préférable de laisser l’OS du téléphone calculer automatiquement le bon pixel-ratio pour le transmettre au navigateur. Afin de forcer le bon niveau de zoom aux navigateurs mobiles, mais aussi pour leur imposer une largeur d'affichage qui ne soit pas égale à 960px (ou autres valeurs selon le navigateur), il vous sera nécessaire d'inclure une balise <meta> "viewport" au sein du <head> de votre document HTML. Généralement, nous définirons une largeur de viewport égale à la largeur d'écran théorique de l’appareil ainsi qu’un niveau de zoom initial égal à 1, soit :



<meta name="viewport" content="width=device-width, initial-scale=1.0" >

"initial-scale" définit le facteur de zoom sur la page en fonction de la valeur calculée par rapport à la fenêtre d'affichage idéale (device-width). Ce facteur est conçu pour contrôler le niveau de zoom lorsque la page est chargée pour la première fois ou que l'orientation est modifiée. Afin de vous assurer que le contenu n'apparaît pas zoomé avant / arrière, l'échelle initiale doit être définie sur 1.0. Néanmoins, la propriété initial-scale accepte comme valeur un nombre comprit entre > 0.0 et 10.0. Si malgré les recommandations, on veut afficher la page à une échelle différente, on peut calculer le facteur de dezoom de la façon suivante. Pour une largeur de fenêtre théorique de 800, affichée à l'écran en 640px, on calculera : 640 / 800 = 0.80 (au lieu de 1.0). Attention, l'utilisation de la balise HTML Meta Viewport, a parfois des incidences sur les propriétés CSS de la Media Query.

extraits des fichiers de code,Capture d'écranCapture d'écran

« Toute la vie est une affaire de choix. Cela commence par : "la tétine ou le téton ?" Et cela s'achève par : "Le chêne ou le sapin ?". »
—Pierre Desproges


Un menu (responsive) et plusieurs recettes

Pour ce qui concerne ce menu en design responsive, j'ai utilisé dans le css deux media-queries successifs, le premier pour une largeur d'écran inférieure à 1024px, le second pour une largeur d'écran inférieure à 720. Nous passerons donc d'un menu horizontal classique placé dans le haut de la page, à un menu vertical calé dans le bord gauche de la fenêtre, pour finir avec un menu déroulant animé en css adapté aux petits écrans. Pour en étudier le fonctionnement, le contenu de la démo au format d'archive 7z est disponible en téléchargement avec ce lien. L'intégration des deux media-queries à la fin du css donne ceci:


...

@media screen and (max-width: 1024px) {
#menu ul{
padding:0;
width:160px;
height:100%;
position:fixed;
}
#menu ul li a {
float:none;
text-align:left;
}
}


@media screen and (max-width: 720px) {
#sandwich {
width: 35px;
margin-top:15px;
}
#menu ul {
width:100%;
height:55px;
position:relative;
}
#menu ul li {
width:100%;
border-bottom:1px solid white;
}
#menu ul li:hover {
background-color:#777;
}
#menu ul li a {
width:100%;
text-align:center;
}
#navigation.slidein {
animation-delay: 0.1s;
animation-duration: 0.4s;
animation-name: slidedown;
animation-fill-mode: forwards
}
@keyframes slidedown {
0% { height: 40px; }
100% { height: 225px; }
}
}

On constatera la présence d'une section "animation" (name, delay, duration, fill-mode), tout à la fin du code ainsi que d'un bloc "@keyframes". Ce sont les éléments qui permettront d'animer le slide-in du menu sans avoir recours au jQuery. La règle @keyframes permet aux auteurs de définir les étapes qui composent la séquence d'une animation CSS. Cela permet de contrôler une animation plus finement que ce qu'on pourrait obtenir avec les transitions. Afin d'utiliser ces règles, on nommera chaque étape et on utilisera ce nom avec la propriété animation-name afin qu'une animation corresponde à la liste des étapes qui la composent. Chaque règle @keyframes contiendra donc théoriquement une liste de sélecteurs d'étapes dont chacune inclus le pourcentage d'avancement de l'animation auquel il correspond ainsi que les informations de styles qui correspondent à cette étape. Dans notre cas, le contenu de la balise animation est assez simple : on renseigne un nom pour celle-ci afin de pouvoir l'appeler via le javascript : slidedown, un délai très court avant de débuter, une durée, est un déroulé (en avant ou en arrière), ici : forwards. Le Keyframes ne comporte que deux étapes, la hauteur de la div au départ (0%), et la hauteur à la fin (100%). Pour lancer l'animation, on utilise un petit script:


const elt = document.getElementById('sandwich');
const nav = document.getElementById('navigation');
 
elt.addEventListener('click', function action() {
if (nav.className != 'slidein') {
nav.className = 'slidein';
elt.src = ("css/img/mini-menu-2.gif");
} else {
nav.className = '';
elt.src = ("css/img/mini-menu.gif");
};
});

Comme on peut le voir, la procédure est là encore très simple et ne comporte aucune fonction jQuery. On place un détecteur d'évènement (" addEventListener ") sur l'icone sandwich pour tester l'exécution d'un clic. lorsque l'évènement se produit, on lance l'animation en appelant son nom (" slidein "), et l'on modifie l'icone du menu en conséquence. l'archive fonctionnelle de la démo pèse 4,4 ko, comporte 3 fichiers : css, javascript et html, ainsi que les deux icones du menu déroulant. Elle est téléchargeable en intégralité en cliquant sur ce lien.

publié le 03/01/2022, à 11h05 par Frédéric Schäfer


Précédentsuivant