Media queries CSS
Le langage CSS (« Cascading Style Sheets », en français « feuilles de style en cascade ») constitue avec HTML et JavaScript le socle de base pour concevoir des sites Web modernes. CSS est un langage de programmation, mais il ne décrit pas les différentes étapes de la résolution d’un problème. Au lieu de cela, c’est un objectif à atteindre qui est défini. C’est pourquoi on dit que CSS est un langage déclaratif, à l’instar de SQL.
Les « media queries », ou requêtes média, qui servent à interroger un périphérique de sortie pour en connaître les propriétés, font partie des CSS. Elles sont utilisées en responsive web design pour adapter l’apparence du contenu. Mais comment fonctionnent-elles exactement ?
- Domaine .eu ou .fr + éditeur de site gratuit pendant 6 mois
- 1 certificat SSL Wildcard par contrat
- Boîte email de 2 Go
Que sont les media queries CSS ?
Les media queries CSS ont été introduites avec la spécification CSS3. Une requête média lie l’attribution des propriétés CSS d’un élément à une ou plusieurs conditions de support/média. Dans le cas le plus basique, on distingue le support sur lequel l’information est présentée, qui peut être un écran, une page imprimée (inclut l’impression au format PDF) ou du texte lu à voix haute :
Support | Explication |
---|---|
all | Tout support de sortie |
screen | Affichage du contenu d’une page Web sur un écran défilant |
Affichage du contenu d’une page Web sur plusieurs pages de taille fixe | |
speech | Lecture à voix haute du contenu d’une page Web par un synthétiseur vocal |
Une requête média CSS est spécifiée dans un bloc de code CSS à l’aide d’une règle '@media' spéciale. Les sélecteurs et règles CSS qu’il contient ne sont activés que dans la condition spécifiée. Par exemple, les éléments qui ne doivent pas être affichés au format page imprimée peuvent être masqués :
/* Masquer les éléments non imprimables */
@media print {
video, audio {
display: none;
}
}
Outre le support utilisé, les requêtes média CSS peuvent être mises en œuvre pour connaître les propriétés exactes du support concerné. Les requêtes média CSS sont la principale fonction à avoir rendu possible le responsive web design.
Les media queries CSS, composante centrale du responsive web design
Le responsive web design, ou design réactif, vise à adapter l’affichage d’un site Web au périphérique de la manière la plus fluide qui soit. Les requêtes média servent à connaître différentes propriétés du périphérique d’affichage, que l’on appelle media features. Il devient ainsi possible de définir des règles de style pour différentes tailles d’écran. Qui plus est, ces règles de style peuvent être optimisées lorsque l’appareil mobile est incliné.
Voici une vue d’ensemble des media features les plus couramment utilisées actuellement en responsive design :
Media feature | Explication |
---|---|
width | Demander la largeur de l’écran en pixels |
height | Demander la hauteur de l’écran en pixels |
orientation | Détecter l’orientation de l’écran (mode portrait ou paysage) |
resolution | Détecter la résolution d’écran disponible |
Voyons quelques exemples. Imaginons le titre principal d’un site Web. HTML fournit l’élément 'h1' à cette fin. Pour commencer, nous définissons les règles de style pour l’élément h1 sans penser au périphérique d’affichage :
h1 {
font-size: 24px;
line-height: 1.25;
}
Ensuite, nous définissons une media query pour demander la largeur de l’écran. Dans cette requête, nous indiquons les règles de style à appliquer au titre à partir de cette largeur. Dans notre exemple, nous agrandissons la taille de la police du titre h1 sur les écrans mesurant au moins 1024 pixels de large :
@media screen and (min-width: 1024px) {
h1 {
font-size: 36px;
}
}
Nous ne modifions ici que la propriété 'font-size' du titre h1. L’interligne est défini par la propriété 'line-height' comme valeur relative et est hérité (car il n’est pas explicitement modifié). Dans notre exemple, l’interligne de l’élément h1 est par défaut de 24px * 1,25 = 30px. Sur les écrans de 1024 pixels de large ou plus, l’interligne augmente en proportion et devient 36px * 1,25 = 45px.
Ce mélange de règles de style existantes et nouvellement définies se retrouve dans le mot « cascade » de CSS : un élément hérite des règles de style des éléments parents ou règles générales déjà définies. Habituellement, on définit les propriétés de base des éléments, puis on écrase sélectivement des propriétés dans certaines conditions.
Autre exemple : imaginons que nous voulions afficher trois éléments dans un conteneur. Les éléments doivent être affichés les uns au-dessous des autres sur l’écran quand l’appareil est tenu à la verticale. Quand l’appareil bascule en mode paysage, la mise en page doit changer afin que les éléments apparaissent côte à côte. Grâce au module de mise en page Flexbox et à une requête média CSS demandant l’orientation de l’appareil, cela peut être réalisé en quelques lignes de HTML et CSS. Pour cela, nous définissons d’abord le conteneur et les éléments contenus en HTML :
<div class="container">
<div class="element">…</div>
<div class="element">…</div>
<div class="element">…</div>
</div>
Nous définissons aussi les règles CSS suivantes. Nous attribuons la propriété 'display: flex' au conteneur et définissons de manière conditionnelle la propriété 'flex-direction' de celui-ci via une requête média CSS. Lorsque l’appareil sera tenu en mode paysage, les éléments s’afficheront en ligne les uns à côté des autres ; lorsqu’il sera tenu en mode portrait, les éléments seront alignés les uns au-dessous des autres :
.container {
display: flex;
}
/* Format paysage */
@media screen and (orientation: landscape) {
.container {
flex-direction: row;
}
}
/* Format portrait */
@media screen and (orientation: portrait) {
.container {
flex-direction: column;
}
}
Outre les dimensions de l’écran et l’orientation de l’appareil, on peut également demander la résolution physique de l’écran au moyen d’une media query. C’est particulièrement intéressant pour l’affichage d’images en pixels. Imaginons qu’un logo soit disponible en deux versions, chacune optimisée pour les écrans à basse et haute résolution. Une technique simple pour afficher le logo qui convient dans chaque cas consiste à placer les deux versions sur le site. À l’aide d’une media query CSS, nous demandons la résolution de l’écran et nous masquons la version qui n’est pas nécessaire à l’aide de 'display: none'. Cette méthode pourrait ressembler à ceci en code HTML et CSS :
<!--—Image haute résolution ---->
<img class="logo--high-res" src="/img/logo-high-res.png" alt="Logo haute résolution">
<!--—Image à faible résolution ---->
<img class="logo--low-res" src="/img/logo-low-res.png" alt="Logo à faible résolution">
/* Masquer une image haute résolution sur un écran à faible résolution */
@media (max-resolution: 149dpi) {
.logo--high-res {
display: none;
}
}
/* Masquer une image à faible résolution sur un écran haute résolution */
@media (min-resolution: 150dpi) {
.logo--low-res {
display: none;
}
}
Dans notre article sur le responsive web design, nous vous présentons d’autres façons d’afficher des images de manière adaptative.
Activer les variables viewport pour le responsive design
Dans nos explications précédentes, nous avons parlé « d’écran » en relation avec la largeur disponible du périphérique de sortie. C’est vrai d’un point de vue conceptuel, mais techniquement ce n’est pas tout à fait exact. Le navigateur fonctionne en interne avec le concept de « viewport ». Pour que la largeur du viewport corresponde réellement à la largeur de l’écran, une déclaration 'meta-viewport' est nécessaire dans la balise '<head>' du document HTML. Sans celle-ci, la page s’affichera sur les appareils mobiles comme sur un poste fixe, à la simple différence que sa taille globale sera considérablement réduite.
<head>
<!-- Activer les CSS Media Queries -->
<meta name="viewport" content="width=device-width, initial-scale=1">
</head>
Comprendre les unités CSS pour le responsive web design
En responsive web design, les éléments doivent s’adapter à la taille de l’écran. Il s’agit souvent de définir les dimensions des éléments dans différentes conditions. La spécification CSS prévoit une multitude d’unités, l’unité de dimension la plus simple étant probablement le pixel. Par exemple, une image de 1080 pixels a des dimensions de 1920 pixels de large sur 1080 pixels de haut.
Le pixel est une entité absolue, et par définition ne s’adapte pas à l’espace disponible. Prenons un exemple qui montre pourquoi cela peut être problématique. Supposons qu’une page Web contienne une image d’une largeur de 1920 pixels. Si nous définissons la largeur de l’image à cette valeur par CSS, l’affichage risque d’être perturbé sur les petits écrans, puisque l’image sortira de l’espace disponible.
Nous définissons ici une image en HTML à l’aide de la balise '<img>' :
<img class="img-1080p" src="/bild-1080p.png">
Dans la feuille CSS, nous fixons la largeur à 1920 pixels :
.img-1080p {
width: 1920px;
}
Dans ce scénario, il serait mieux d’utiliser une unité relative plutôt que des pixels. Depuis ses premiers jours, CSS connaît le pourcentage comme unité relative. Si nous définissons la largeur de l’image à « 100 % » via CSS, l’image s’adaptera de manière fluide à l’espace disponible. Cela fonctionne parce que les pourcentages se rapportent toujours à l’élément englobant.
img {
width: 100%;
}
Nous avons fait un grand pas vers notre objectif d’adapter la largeur d’une image à l’espace disponible. Cependant, nous avons créé un nouveau problème : sur un écran de plus de 1920 pixels, l’image sera agrandie et donc pixellisée. Par conséquent, nous devons également limiter la largeur maximale de l’image à ses dimensions réelles en pixels :
.img-1080p {
/* hérité implicitement de `img` */
/* width: 100%; */
max-width: 1920px;
}
CSS reconnaît un certain nombre d’autres unités, en plus du pixel et du pourcentage. Les unités relatives em, rem et vw, vh offrent toutes des utilisations intéressantes en responsive design. Voici un aperçu des unités CSS les plus couramment utilisées pour obtenir un design adaptatif :
Unité CSS | Utilisation |
---|---|
rem | Taille de la police du corps de texte, 'max-width' des éléments de mise en page ; 'width' des éléments |
% | 'width' des images et des éléments de mise en page, éventuellement limitée par 'max-width' |
vw, vh | Taille de la police des titres, des textes hero, des dimensions des éléments de remplissage de l’écran |
em | Définition des breakpoints, 'max-width' des éléments de mise en page |
px | Définition des breakpoints, 'max-width' des images |
Comprendre les media queries avancées
Outre les requêtes média basiques présentées jusqu’ici, il est aussi possible d’écrire des media queries CSS complexes. CSS fournit à cette fin les opérateurs logiques 'and', 'or', et 'not'. Voici un exemple de requête complexe :
@media screen and (min-width: 30em) and (orientation: landscape) { /* … */ }
En plus des media features déjà existantes, qui peuvent être interrogées au moyen des media queries, d’autres fonctions intéressantes sont prévues à l’avenir. La spécification « CSS Media Queries Level 5 » (CSS5) prévoit les nouvelles options d’interrogation suivantes :
Media feature | Explication |
---|---|
light-level | Détecter la luminosité ambiante |
prefers-color-scheme | Choisir le thème clair ou sombre |
prefers-contrast | Choisir le mode de contraste élevé |
Une autre nouveauté attendue avec la parution de CSS5 est les container queries. Grâce à elles, il sera permis pour la première fois de lier les règles de style des éléments aux propriétés du conteneur qui les entoure. Les container queries contrastent donc avec les media queries CSS, qui interrogent les propriétés globales du périphérique d’affichage. La mise en œuvre des container queries permettra de gérer les cas particuliers pour lesquels on recourait jusqu’à présent à JavaScript ou à des media queries complexes.
Comprendre les breakpoints CSS
Dans le contexte du responsive web design et des media queries CSS, le terme « breakpoint » (point de rupture) revient souvent. Un breakpoint est en fait une largeur d’écran définie pour laquelle un ensemble de règles CSS déterminées à l’aide de media queries est activé. On peut visualiser les breakpoints définis sur un site Web en ouvrant les outils de développement dans le navigateur. Si l’affichage adaptatif est actif, les breakpoints apparaissent sous forme de barres colorées au-dessus de la page Web.
Comprendre le concept mobile first, les processeurs CSS et les utility frameworks CSS
Une bonne pratique reconnue pour concevoir des sites web adaptatifs est l’approche mobile first. Quand un site Web est développé suivant cette approche, le style est pensé en premier lieu pour les petits écrans. Ces spécifications de style constituent le socle de base du design. Sur cette base, plusieurs breakpoints sont définis pour des écrans de plus en plus grands. Au sein des breakpoints, de nouvelles règles de style sont définies de manière sélective pour les éléments et remplacent les règles existantes pour les écrans plus petits.
L’approche mobile first est bien illustrée par le célèbre utility framework CSS appelé « Tachyons ». Celui-ci définit trois breakpoints par défaut : 'not-small', 'medium' et 'large’ :
/* Tachyons Breakpoints */
/* 'not-small' Breakpoint */
@media screen and (min-width: 30em) { /* … */ }
/* 'medium' Breakpoint */
@media screen and (min-width: 30em) and (max-width: 60em) { /* … */ }
/* 'large' Breakpoint */
@media screen and (min-width: 60em) { /* … */ }
Notez que dans l’approche mobile first, il n’y a pas de breakpoint 'small'. Les spécifications pour les petits appareils sont simplement définies sans breakpoint.
Breakpoint Tachyons | Explication |
---|---|
not-small | Comprend les largeurs d’écran des breakpoints 'medium' et 'large' |
medium | Comprend les largeurs d’écran entre les breakpoints 'not-small' et 'large' |
large | Comprend uniquement les grands écrans |
Au sein des breakpoints, des règles de style sont définies pour les éléments dont l’affichage doit être adapté à des écrans de différentes tailles. Vous comprenez peut-être déjà que cette centralisation de la codebase CSS d’un projet Web pose problème. Normalement, il est préférable de rassembler toutes les propriétés CSS d’un élément dans un fichier séparé.
- Large choix de templates, domaine et email
- Outils SEO et plus de 17 000 photos libres de droit
- Prise de rendez-vous en ligne, simple et rapide
Comprendre les pré- et post-processeurs CSS
Pour modulariser le code CSS d’un projet, différents préprocesseurs CSS ont d’abord été utilisés. Vous connaissez peut-être les langages Sass, Less ou Stylus. Par la suite, un post-processeur CSS est venu s’ajouter avec le projet Node.js PostCSS. Toutes les technologies susmentionnées permettent d’encapsuler les media queries CSS sous un sélecteur CSS. De cette manière, les règles de style d’un élément peuvent être définies collectivement pour toutes les conditions de média. Voici un exemple avec Stylus.
Fichier Stylus 'text.styl' pour les propriétés du texte :
// Définitions Mobile First
p
font-size: 16px
// Définitions pour le Breakpoint 'not-small'
@media screen and (min-width: 30em)
font-size: 18px
Fichier Stylus 'link.styl' pour les propriétés des liens :
// Définitions Mobile First
a
color: blue
// Définitions pour le Breakpoint 'not-small'
@media screen and (min-width: 30em)
text-decoration: underline
Le préprocesseur Stylus traduit les fichiers en CSS et regroupe les règles des media queries CSS insérées sous un seul breakpoint. Le code Stylus présenté se traduit par le code CSS suivant :
/* Définitions mobile first */
p {
font-size: 16px;
}
a {
color: blue;
}
/* Définitions pour le Breakpoint 'not-small' */
@media screen and (min-width: 30em) {
p {
font-size: 18px;
}
a {
text-decoration: underline;
}
}
Comprendre les utility frameworks CSS
La méthode consistant à encapsuler les requêtes média CSS dans les règles de style d’un élément et à les traiter à l’aide du processeur CSS fonctionne. Néanmoins, elle oblige toujours le développeur à faire des allers-retours entre les niveaux HTML et CSS. Il est également nécessaire d’attribuer des noms de classe uniques aux éléments en HTML. Tout cela entraîne une complexité indésirable. C’est là qu’interviennent les utility frameworks CSS, une technologie reconnue de nos jours.
Un utility framework associe des propriétés CSS atomiques à des breakpoints. Les classes CSS qui en résultent peuvent être attribuées à n’importe quel élément du code HTML. Il devient alors possible de définir des mises en page et des composants adaptatifs uniquement en HTML, sans avoir à écrire de code CSS. L’utilisation d’un utility framework CSS permet un prototypage rapide et convient idéalement au développement de composants. Pour cette raison, les utility frameworks CSS sont souvent employés en relation avec des technologies orientées composants, telles que React et Vue.
Voyons un autre exemple, emprunté au framework Tachyons. Jetez un œil au code CSS ci-dessous. Nous définissons d’abord les classes 'mw1' à 'mw3', qui limitent la largeur maximale de tout élément à des valeurs comprises entre '1rem' et '3rem'. Ensuite, nous définissons des classes CSS correspondantes dans les breakpoints 'medium' et 'large', qui incluent l’abréviation du breakpoint concerné dans leur nom :
/* Tachyons */
/* Taille mobile first */
.mw1 { max-width: 1rem; }
.mw2 { max-width: 2rem; }
.mw3 { max-width: 3rem; }
/* Breakpoint 'medium' */
@media screen and (min-width: 30em) and (max-width: 60em) {
.mw1-m { max-width: 1rem; }
.mw2-m { max-width: 2rem; }
.mw3-m { max-width: 3rem; }
}
/* Breakpoint 'large' */
@media screen and (min-width: 60em) {
.mw1-l { max-width: 1rem; }
.mw2-l { max-width: 2rem; }
.mw3-l { max-width: 3rem; }
}
Grâce à ces classes CSS, nous pouvons écrire des éléments adaptatifs entièrement en HTML. L’extrait de code HTML suivant définit une image dont la largeur maximale est de '1rem' sur les petits écrans. L’image s’adapte automatiquement à la largeur d’écran disponible. Sur les écrans de taille moyenne, l’élément occupera au maximum '2rem', sur les grands écrans '3rem'.
<img class="mw1 mw2-m mw3-l" src="/image.png" alt="Une image responsive">
Les « utility frameworks » CSS sont un vaste ensemble de classes atomiques dont chacune détermine une seule propriété CSS. En plus des dimensions d’un élément, cela inclut des informations sur la typographie, les couleurs et à peu près n’importe quelle autre caractéristique imaginable. Pour chaque propriété atomique, un « utility framework » contient des classes pour chaque breakpoint défini. En combinant plusieurs classes, il est possible d’assembler un nombre presque infini d’éléments entièrement adaptatifs.
Le framework Tachyons évoqué plus haut a déjà plusieurs années et n’est plus entretenu. Toutefois, en raison de sa relative simplicité, Tachyons mérite d’être considéré pour apprendre le responsive web design. Le moyen le plus facile de comprendre cette méthode est de regarder les composants Tachyons. Il s’agit d’éléments illustratifs qui sont entièrement définis à l’aide de classes utility.
Une version moderne existe aujourd’hui avec TailwindCSS, qui peut être considéré comme le successeur spirituel de Tachyons. TailwindCSS comporte certains avantages par rapport à Tachyons. Ainsi, le projet est toujours activement développé et prend en charge d’emblée de nombreux systèmes populaires de développement front-end. Qui plus est, TailwindCSS peut être entièrement personnalisé en fonction des besoins spécifiques de votre projet. Tous les préréglages, tels que les breakpoints, l’échelle de la taille de police, etc. sont facilement configurables.
Si les utility frameworks CSS sont pratiques à utiliser, ils présentent néanmoins un inconvénient majeur : il faut parfois une grande quantité de classes atomiques pour définir un élément. En outre, par défaut, le fichier texte source CSS contient des classes pour l’ensemble des combinaisons de valeurs de propriétés CSS et de breakpoints. Dans le cas de TailwindCSS, les classes se comptent en milliers, si bien que le fichier CSS non compressé pèse plusieurs mégaoctets, une situation intenable du point de vue des performances.
Heureusement, TailwindCSS y remédie de deux manières. D’une part, le framework connaît l’instruction '@apply', qui sert à grouper des combinaisons de classes utility utilisées plusieurs fois sous un nouveau nom de classe. D’autre part, TailwindCSS prend en charge l’utilitaire PurgeCSS. Celui-ci est employé dans le cadre du processus de build pour supprimer toutes les classes utility inutilisées du build de production. PurgeCSS traite les modèles HTML du projet et n’inclut que les classes CSS trouvées dans le fichier source CSS généré. Cela permet de réduire le fichier source à une taille acceptable.