La plupart des sites web modernes utilisent des techniques de conception web responsive pour s’assurer qu’ils sont beaux, lisibles et utilisables sur des appareils de toute taille d’écran, c’est-à-dire des téléphones mobiles, des tablettes, des ordinateurs portables, des écrans de PC de bureau, des télévisions, des projecteurs, etc.

Les sites utilisant ces techniques ont un seul modèle, qui modifie la mise en page en fonction des dimensions de l’écran :

  • Les écrans plus petits présentent généralement une vue linéaire à une seule colonne où les contrôles de l’interface utilisateur, comme les menus, sont activés en cliquant sur les icônes (hamburger).
  • Les écrans plus grands affichent plus d’informations, peut-être avec des colonnes latérales alignées horizontalement. Les contrôles de l’interface utilisateur, comme les éléments de menu, peuvent toujours être visibles pour un accès plus facile.

Une grande partie du responsive web design est l’implémentation d’une media query CSS ou JavaScript pour détecter la taille de l’appareil et servir automatiquement le design approprié pour cette taille. Nous allons voir pourquoi ces requêtes sont importantes et comment les utiliser, mais d’abord, parlons du responsive design en général.

Pourquoi le Responsive Design est-il important ?

Il est impossible de proposer une mise en page unique et de s’attendre à ce qu’elle fonctionne partout.

Lorsque les téléphones mobiles ont commencé à avoir un accès rudimentaire au web au début des années 2000, les propriétaires de sites créaient souvent deux ou trois modèles de pages distincts vaguement basés sur les vues des mobiles et des ordinateurs de bureau. Cela est devenu de moins en moins pratique à mesure que la variété des appareils augmentait de façon exponentielle.

Aujourd’hui, il existe de nombreuses tailles d’écran, allant des minuscules écrans de montre-bracelet aux énormes moniteurs 8 K et au-delà. Même si vous ne considérez que les téléphones portables, les appareils récents peuvent avoir une résolution plus élevée que de nombreux ordinateurs portables bas de gamme.

L’utilisation des mobiles a également dépassé celle des ordinateurs de bureau. À moins que votre site ne soit destiné à un ensemble spécifique d’utilisateurs, vous pouvez vous attendre à ce que la majorité des gens y accèdent depuis un smartphone. Les appareils à petit écran ne sont plus une réflexion après coup et doivent être pris en compte dès le départ, même si la plupart des concepteurs de sites web, des développeurs et des clients continuent d’utiliser un PC standard.

Google a reconnu l’importance des appareils mobiles. Les sites sont mieux classés dans les recherches Google lorsqu’ils sont utilisables et performants sur un smartphone. Un bon contenu reste vital, mais un site à chargement lent qui ne s’adapte pas aux dimensions de l’écran de votre base d’utilisateurs pourrait nuire à votre entreprise.

Enfin, pensez à l’accessibilité. Un site qui fonctionne pour tout le monde, quel que soit l’appareil qu’ils utilisent, touchera un public plus large. L’accessibilité est une obligation légale dans de nombreux pays, mais même si ce n’est pas le cas là où vous êtes, considérez que plus de spectateurs entraîneront plus de conversions et une meilleure rentabilité.

Comment fonctionne le responsive design ?

La base du responsive design est media query : une technologie CSS qui peut appliquer des styles en fonction de mesures telles que le type de sortie (écran, imprimante ou même parole), les dimensions de l’écran, le ratio d’aspect de l’affichage, l’orientation de l’appareil, la profondeur des couleurs et la précision du pointeur. Media query peut également prendre en compte les préférences des utilisateurs, notamment la réduction des animations, le mode clair/sombre et un contraste plus élevé.

Les exemples que nous avons montrés montrent media query utilisant uniquement la largeur de l’écran, mais les sites peuvent être beaucoup plus flexibles. Reportez-vous à l’ensemble des options sur MDN pour plus de détails.

La prise en charge de media query est excellente et existe dans les navigateurs depuis plus de dix ans. Seuls IE8 et les versions inférieures n’ont aucune prise en charge. Ils ignorent les styles appliqués par media query, mais cela peut parfois être un avantage (lisez plus loin dans la section Meilleures pratiques ).

Il existe trois façons standard d’appliquer des styles à l’aide de media query. La première charge des feuilles de style spécifiques dans le code HTML. Par exemple, la balise suivante charge la feuille de style wide.css lorsqu’un appareil a un écran d’au moins 800 pixels de large :

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

Deuxièmement, les feuilles de style peuvent être chargées de manière conditionnelle dans les fichiers CSS à l’aide d’une at-rule @import:

/* main.css */
@import url('wide.css') screen and (min-width: 800px);

Plus généralement, vous appliquerez media query dans les feuilles de style en utilisant un bloc at-rule CSS @media qui modifie des styles spécifiques. Par exemple :

/* default styles */
main {
  width: 400px;
}

/* styles applied when screen has a width of at least 800px */
@media screen and (min-width: 800px) {
  main {
    width: 760px;
  }
}

Les développeurs peuvent appliquer toutes les règles de media query nécessaires pour adapter la mise en page d’un site.

Meilleures pratiques pour media query

Lorsque les media queries ont été conçues pour la première fois, de nombreux sites ont opté pour un ensemble de mises en page rigoureusement fixes. C’est conceptuellement plus facile à concevoir et à coder car cela reproduit efficacement un ensemble limité de modèles de pages. Par exemple :

  1. Les largeurs d’écran inférieures à 600px utilisent une mise en page de type mobile de 400px de large.
  2. Les largeurs d’écran comprises entre 600px et 999px utilisent une mise en page de type tablette de 600px de large.
  3. Les largeurs d’écran supérieures à 1 000px utilisent une mise en page de type ordinateur de bureau de 1000px de large.

Cette technique est imparfaite. Les résultats sur les très petits et très grands écrans peuvent paraître médiocres, et une maintenance CSS peut être nécessaire lorsque les appareils et les tailles d’écran changent au fil du temps.

Une meilleure option consiste à utiliser un design fluide mobile-first avec des points de terminaison qui adaptent la mise en page à certaines tailles. En substance, la mise en page par défaut utilise les styles les plus simples pour les petits écrans qui positionnent les éléments dans des blocs verticaux linéaires.

Par exemple, <article> et <aside> à l’intérieur d’un conteneur <main> :

/* default small-screen device */
main {
  width: 100%;
}

article, aside {
  width: 100%;
  padding: 2em;
}

Voici le résultat dans tous les navigateurs – même les très anciens qui ne prennent pas en charge les media queries :

Exemple de capture d'écran sans prise en charge des media queries.
Exemple de capture d’écran sans prise en charge des media queries.

Lorsque les media queries sont prises en charge et que l’écran dépasse une largeur spécifique, disons 500px, la fonction <article> et <aside> peuvent être positionnés horizontalement. Cet exemple utilise une grille CSS, où le contenu principal utilise environ deux tiers de la largeur, et le contenu secondaire utilise le tiers restant :

/* larger device */
@media (min-width : 500px) {
  main {
    display : grid ;
    grid-template-columns : 2fr 1fr ;
    gap : 2em ;
  }

  article, aside {
    width : auto ;
    padding : 0 ;
  }
}

Voici le résultat sur des écrans plus grands :

Exemple de capture d'écran avec prise en charge de media query.
Exemple de capture d’écran avec prise en charge de media query.

Alternatives à media Query

Les conceptions responsives peuvent également être mises en œuvre dans les CSS modernes à l’aide de propriétés plus récentes qui adaptent intrinsèquement la mise en page sans examiner les dimensions du viewport. Les options comprennent :

    • calc, min-width, max-width, min-height, max-height, et la propriété plus récente clamp peuvent toutes définir des dimensions qui dimensionnent les éléments en fonction de limites connues et de l’espace disponible.
    • Les unités viewport vw, vh, vmin, et vmax peuvent dimensionner les éléments en fonction des fractions de la dimension de l’écran.
    • Le texte peut être affiché dans des colonnes CSS qui apparaissent ou disparaissent selon l’espace disponible.
    • Les éléments peuvent être dimensionnés en fonction des tailles de leurs éléments enfants à l’aide des dimensions min-content, fit-content, et max-content.
    • CSS flexbox peut envelopper – ou ne pas envelopper – les éléments lorsqu’ils commencent à dépasser l’espace disponible.
    • Les éléments de la grille CSS peuvent être dimensionnés avec des unités de fraction fr proportionnelles. La fonction CSS repeat peut être utilisée conjointement avec minmax, auto-fit, et auto-fill pour allouer l’espace disponible.
    • Les nouvelles requêtes de conteneur CSS  (actuellement) expérimentales peuvent réagir à l’espace partiel disponible pour un composant dans une mise en page.

Ces options dépassent le cadre de cet article, mais elles sont souvent plus pratiques que les media queries plus grossières, qui ne peuvent répondre qu’aux dimensions de l’écran. Si vous pouvez réaliser une mise en page sans media queries, elle utilisera probablement moins de code, sera plus efficace et nécessitera moins de maintenance au fil du temps.

Cela dit, il existe des situations où les media queries restent la seule option de mise en page viable. Elles restent essentielles lorsque vous devez prendre en compte d’autres facteurs d’écran tels que les ratios d’aspect, l’orientation de l’appareil, la profondeur des couleurs, la précision du pointeur ou les préférences de l’utilisateur telles que la réduction des animations et le mode clair/sombre.

Avez-vous besoin de media queries dans JavaScript ?

Jusqu’à présent, nous avons surtout parlé de CSS. C’est parce que la plupart des problèmes de mise en page peuvent – et devraient – être résolus uniquement avec CSS.

Cependant, il y a des situations où il est pratique d’utiliser une media query dans JavaScript au lieu de CSS, comme dans les cas suivants :

  • Un composant, comme un menu, a des fonctionnalités différentes sur les petits et les grands écrans.
  • Le passage du portrait au paysage et vice-versa affecte la fonctionnalité d’une application web.
  • Un jeu tactile doit modifier la disposition de <canvas>ou adapter les boutons de contrôle.
  • Une appli web adhère aux préférences des utilisateurs, comme le mode sombre/clair, l’animation réduite, la grossièreté du toucher, etc.

Les sections suivantes présentent trois méthodes qui utilisent des media queries – ou des options similaires aux media queries – dans JavaScript. Tous les exemples renvoient une chaîne d’état où :

  • Vue small = un écran dont la largeur est inférieure à 400 pixels ;
  • Vue medium = un écran dont la largeur est comprise entre 400 et 799 pixels ; et
  • Vue large = un écran d’une largeur de 800 pixels ou plus.

Option 1 : Surveiller les dimensions de la fenêtre d’affichage

C’était la seule option à l’époque sombre qui a précédé la mise en œuvre des media queries. JavaScript écoutait les événements de « redimensionnement » du navigateur, analysait les dimensions de la fenêtre d’affichage à l’aide de window.innerWidth et window.innerHeight (ou document.body.clientWidth et document.body.clientHeight dans les anciens IE), et réagissait en conséquence.

Ce code envoie la chaîne calculée small, medium ou large à la console :

const
  screen = {
    small : 0,
    medium : 400,
    large : 800
  } ;

// observe window resize
window.addEventListener('resize', resizeHandler) ;

// initial call
resizeHandler() ;

// calculate size
function resizeHandler() {

  // get window width
  const iw = window.innerWidth ;
 
  // determine named size
  let size = null ;
  for (let s in screen) {
    if (iw >= screen[s]) size = s ;
  }

  console.log(size) ;
}

Vous pouvez voir une démonstration fonctionnelle ici. (Si vous utilisez un navigateur de bureau, ouvrez ce lien dans une nouvelle fenêtre pour faciliter le redimensionnement. Les utilisateurs de mobiles peuvent faire pivoter l’appareil)

L’exemple ci-dessus examine la taille de la fenêtre d’affichage lorsque le navigateur est redimensionné, détermine si elle est petite, moyenne ou grande et la définit comme une classe sur l’élément body, ce qui modifie la couleur d’arrière-plan.

Les avantages de cette méthode sont les suivants :

  • Elle fonctionne dans tous les navigateurs qui peuvent exécuter JavaScript, même les anciennes applications.
  • Vous saisissez les dimensions exactes et vous pouvez réagir en conséquence.

Les inconvénients :

  • C’est une vieille technique qui nécessite beaucoup de code.
  • Est-ce trop exact ? Avez-vous vraiment besoin de savoir quand la largeur est de 966px par rapport à 967px ?
  • Vous devrez peut-être faire correspondre manuellement les dimensions à une media query CSS correspondante.
  • Les utilisateurs peuvent redimensionner rapidement le navigateur, ce qui oblige la fonction de gestion à s’exécuter à nouveau à chaque fois. Cela peut surcharger les navigateurs plus anciens et plus lents en étranglant l’événement. Il ne peut être déclenché qu’une fois toutes les 500 millisecondes.

En résumé, ne surveillez pas les dimensions de la fenêtre d’affichage, sauf si vous avez des exigences de dimensionnement très spécifiques et complexes.

Option 2 : Définir et surveiller une propriété personnalisée CSS (variable)

Il s’agit d’une technique légèrement inhabituelle qui modifie la valeur d’une chaîne de propriété personnalisée en CSS lorsqu’une media query est déclenchée. Les propriétés personnalisées sont prises en charge par tous les navigateurs modernes (mais pas par IE).

Dans l’exemple ci-dessous, --screen custom property est définie sur « small », « medium » ou « large » dans un bloc de code @media :

body {
  --screen : "small";
  background-color : #cff;
  text-align : center;
}

@media (min-width : 400px) {
 
  body {
    --screen : "medium";
    background-color : #fcf;
 
}

@media (min-width : 800px) {
 
  body {
    --screen : "large";
    background-color : #ffc;
  }
 
}

La valeur peut être sortie dans le CSS seul à l’aide d’un pseudo-élément (mais notez qu’elle doit être contenue entre des guillemets simples ou doubles) :

p::before {
  content : var(--screen);
}

Vous pouvez récupérer la valeur de la propriété personnalisée en utilisant JavaScript :

const screen = getComputedStyle(window.body)
                 .getPropertyValue('--screen');

Mais ce n’est pas tout à fait ça, car la valeur renvoyée contient tous les espaces et caractères de citation définis après les deux points dans le CSS. La chaîne de caractères sera « large », donc un petit toilettage est nécessaire :

// returns small, medium, or large in a string
const screen = getComputedStyle(window.body)
                 .getPropertyValue('--screen')
                 .replace(/\W/g, '');

Vous pouvez voir une démonstration fonctionnelle ici. (Si vous utilisez un navigateur de bureau, ouvrez ce lien dans une nouvelle fenêtre pour faciliter le redimensionnement. Les utilisateurs de mobiles peuvent faire pivoter l’appareil)

L’exemple examine la valeur CSS toutes les deux secondes. Cela nécessite un peu de code JavaScript, mais il est nécessaire de sonder les changements – vous ne pouvez pas détecter automatiquement que la valeur de la propriété personnalisée a changé en utilisant CSS.

Il n’est pas non plus possible d’écrire la valeur dans un pseudo-élément et de détecter le changement à l’aide d’un DOM Mutation Observer. Les pseudo-éléments ne sont pas une « vraie » partie du DOM !

Les avantages :

  • Il s’agit d’une technique simple qui utilise principalement le CSS et correspond aux véritables media queries.
  • Toutes les autres propriétés CSS peuvent être modifiées en même temps.
  • Il n’y a pas besoin de dupliquer ou d’analyser les chaînes media query JavaScript.

Le principal inconvénient est que vous ne pouvez pas réagir automatiquement à un changement de dimension de la fenêtre d’affichageu du navigateur. Si l’utilisateur fait pivoter son téléphone de l’orientation portrait à l’orientation paysage, le JavaScript ne le saura jamais. Vous pouvez interroger fréquemment les changements, mais c’est inefficace et cela entraîne le décalage que vous voyez dans notre démonstration.

La surveillance des propriétés personnalisées CSS est une technique novatrice, mais elle n’est pratique que lorsque :

  1. La mise en page peut être fixée au moment où une page est initialement rendue. Un kiosque ou un terminal de point de vente est une possibilité, mais ceux-ci ont probablement des résolutions fixes et une seule mise en page, donc les media queries JavaScript ne sont pas pertinentes.
  2. Le site ou l’application exécute déjà des fonctions fréquentes basées sur le temps, comme l’animation d’un jeu. La propriété personnalisée pourrait être vérifiée en même temps pour déterminer si des changements de mise en page sont nécessaires.

Option 3 : Utiliser l’API matchMedia

L’API matchMedia est légèrement inhabituelle mais elle vous permet d’implémenter une media query JavaScript. Elle est prise en charge par la plupart des navigateurs à partir d’IE10. Le constructeur renvoie un objet MediaQueryList dont la propriété matches est évaluée à true ou false pour sa media query spécifique.

Le code suivant affiche true lorsque la largeur de la fenêtre du navigateur est de 800px ou plus :

const mqLarge = window.matchMedia( '(min-width : 800px)' );
console.log( mqLarge.matches );

Un événement « change » peut être appliqué à l’objet MediaQueryList. Il est déclenché chaque fois que l’état de la propriété matches change : Elle devient true (plus de 800px) après avoir été précédemment false (moins de 800px) ou vice versa.

La fonction du gestionnaire de réception reçoit l’objet MediaQueryList comme premier paramètre :

const mqLarge = window.matchMedia( '(min-width : 800px)' );
mqLarge.addEventListener('change', mqHandler);

// media query handler function
function mqHandler(e) {
 
  console.log(
    e.matches ? 'large' : 'not large'
  );
 
}

Le gestionnaire s’exécute uniquement lorsque la propriété matches change. Il ne s’exécutera pas lorsque la page est initialement chargée, vous pouvez donc appeler la fonction directement pour déterminer l’état initial :

// initial state
mqHandler(mqLarge);

L’API fonctionne bien lorsque vous vous déplacez entre deux états distincts. Pour analyser trois états ou plus, comme small, medium et large, il faudra plus de code.

Commencez par définir un objet d’état d’écran avec des objets matchMedia associés :

const
  screen = {
    small : null,
    medium : window.matchMedia( '(min-width : 400px)' ),
    large : window.matchMedia( '(min-width : 800px)' )
  };

Il n’est pas nécessaire de définir un objet matchMedia sur l’état small car le gestionnaire d’événements medium se déclenchera lors du passage de small à medium.

Des récepteurs d’événements peuvent ensuite être définis pour les événements medium et large . Ceux-ci appellent la même fonction de gestionnaire mqHandler() :

// media query change events
for (let [scr, mq] of Object.entries(screen)) {
  if (mq) mq.addEventListener('change', mqHandler);
}

La fonction du gestionnaire doit vérifier tous les objets MediaQueryList pour déterminer si small, medium ou large est actuellement actif. Les correspondances doivent être effectuées dans l’ordre des tailles car une largeur de 999px correspondrait à la fois à medium et à large – seul le plus grand doit « gagner » :

// media query handler function
function mqHandler() {
 
  let size = null;
  for (let [scr, mq] of Object.entries(screen)) {
    if (!mq || mq.matches) size = scr;
  }
 
  console.log(size);
 
}

Vous pouvez voir une démonstration fonctionnelle ici. (Si vous utilisez un navigateur de bureau, ouvrez ce lien dans une nouvelle fenêtre pour faciliter le redimensionnement. Les utilisateurs de mobiles peuvent faire pivoter l’appareil)

Les exemples d’utilisation sont les suivants :

  1. Des media queries dans du CSS pour définir et afficher une propriété personnalisée (comme indiqué dans l’option 2 ci-dessus).
  2. Des media queries identiques dans les objets matchMedia pour surveiller les changements de dimension en JavaScript. La sortie JavaScript changera exactement au même moment.

Les principaux avantages de l’utilisation de l’API matchMedia sont les suivants :

  • Elle est pilotée par les événements et efficace pour traiter les changements de media query.
  • Elle utilise des chaînes de media queries identiques à celles du CSS.

Les inconvénients :

  • La gestion de deux ou plusieurs media queries nécessite plus de réflexion et de logique de code.
  • Vous devez probablement dupliquer les chaînes de media query dans le code CSS et JavaScript. Cela peut entraîner des erreurs si vous ne les gardez pas synchronisées.

Pour éviter les incompatibilités de media query, vous pouvez envisager d’utiliser des jetons de conception dans votre système de construction. Les chaînes de media queries sont définies dans un fichier JSON (ou similaire) et les valeurs sont insérées dans le code CSS et JavaScript au moment de la création.

En résumé, l’API matchMedia est probablement le moyen le plus efficace et le plus pratique de mettre en œuvre une media query JavaScript. Elle comporte quelques bizarreries, mais c’est la meilleure option dans la plupart des situations.

Résumé

Les options de dimensionnement CSS intrinsèques sont de plus en plus viables, mais les media queries restent la base du responsive web design pour la plupart des sites. Elles seront toujours nécessaires pour gérer les mises en page plus complexes et les préférences des utilisateurs, comme le mode clair/sombre.

Essayez de garder les media queries uniquement en CSS lorsque c’est possible. Lorsque vous n’avez pas d’autre choix que de vous aventurer dans le royaume de JavaScript, l’API matchMedia fournit un contrôle supplémentaire pour les composants de media query JavaScript, qui nécessitent une fonctionnalité supplémentaire basée sur les dimensions.

Vous avez d’autres conseils pour mettre en œuvre une media query JavaScript ? Partagez-les dans la section des commentaires !

Craig Buckler

Freelance UK web developer, writer, and speaker. Has been around a long time and rants about standards and performance.