Une media query CSS applique un bloc de styles uniquement quand l’appareil ou le navigateur remplit une condition : une largeur de viewport minimale, une orientation paysage ou un thème sombre, par exemple. @media (min-width: 48rem) { ... } signifie « applique ces règles quand le viewport fait au moins 48rem de large ». Ce sont les media queries qui permettent à une même page d’adapter sa mise en page entre téléphone, tablette et ordinateur.
Syntaxe de base
@media (min-width: 768px) {
.sidebar { display: block; }
}
Une media query comporte trois parties facultatives :
- un type de média :
screen,printouall(par défaut) ; - une ou plusieurs caractéristiques média entre parenthèses, comme
(min-width: 768px)ou(orientation: landscape); - des opérateurs logiques pour les combiner :
and,,(ou) etnot.
@media screen and (min-width: 768px) and (orientation: landscape) { ... }
@media (max-width: 480px), (orientation: portrait) { ... }
@media not print { ... }
On peut aussi appliquer une media query à toute une feuille de style : <link rel="stylesheet" href="print.css" media="print">.
min-width ou max-width
min-width signifie « au moins cette largeur » ; max-width, « au plus cette largeur ». Le sens choisi détermine la façon d’écrire le reste du CSS.
- Mobile first (recommandé) : les styles de base visent le téléphone, et les requêtes
min-widthajoutent la mise en page des écrans plus larges. Voir le design mobile first. - Desktop first : les styles de base visent l’ordinateur, et les requêtes
max-widthdéfont ce qu’il faut pour les petits écrans.
/* Mobile first */
.nav { flex-direction: column; }
@media (min-width: 48rem) {
.nav { flex-direction: row; }
}
Mélanger les deux sens dans un même projet crée des chevauchements et des trous. Choisissez-en un, et réservez l’autre à de petites exceptions.
La syntaxe moderne par plages
Media Queries Level 4 ajoute des opérateurs de comparaison, plus lisibles et qui évitent les erreurs d’un pixel :
@media (width >= 48rem) { ... }
@media (40rem <= width < 64rem) { ... }
Cette syntaxe est prise en charge par tous les grands navigateurs actuels (Chrome et Edge depuis la version 104, Firefox depuis la 63, Safari depuis la 16.4). Si vous devez gérer d’anciennes versions de Safari, continuez avec min-width et max-width, ou laissez un outil de build faire la conversion.
Attention : (width < 768px) et (max-width: 767px) ne sont pas équivalents. Le premier correspond aussi à 767,5 px, ce qui peut arriver sur les écrans à densité de pixels fractionnaire.
Media queries pour mobile : exemples courants
Empiler les colonnes sur petit écran :
.grid { display: grid; gap: 1rem; }
@media (min-width: 40rem) {
.grid { grid-template-columns: repeat(2, 1fr); }
}
@media (min-width: 64rem) {
.grid { grid-template-columns: repeat(4, 1fr); }
}
Réduire les espacements sur téléphone :
.section { padding: 2rem 1rem; }
@media (min-width: 64rem) {
.section { padding: 6rem 2rem; }
}
Téléphone en paysage avec peu de hauteur :
@media (orientation: landscape) and (max-height: 30rem) {
.site-header { position: static; }
}
Ce dernier cas est souvent oublié. Un en-tête fixe qui passe bien en portrait peut occuper un tiers de l’écran en paysage.
Le choix des largeurs est une autre question, traitée dans les breakpoints responsive.
Les caractéristiques média au-delà de la largeur
| Caractéristique | Exemple | À utiliser pour |
|---|---|---|
orientation |
(orientation: landscape) |
Changer la mise en page quand on tourne un téléphone ou une tablette |
hover |
(hover: hover) |
Effets de survol uniquement sur les appareils qui le permettent |
pointer |
(pointer: coarse) |
Des cibles plus grandes sur écran tactile |
prefers-color-scheme |
(prefers-color-scheme: dark) |
Thème sombre |
prefers-reduced-motion |
(prefers-reduced-motion: reduce) |
Désactiver les animations |
resolution |
(min-resolution: 2dppx) |
Images haute densité en arrière-plan CSS |
display-mode |
(display-mode: standalone) |
Styler une web app installée |
hover et pointer comptent plus qu’il n’y paraît. Un ordinateur portable tactile ou une tablette affichant une mise en page large n’a pas de survol : protégez les menus au survol avec @media (hover: hover).
Exprimez les breakpoints en rem ou em
Les media queries en rem ou em suivent la taille de police réglée par l’utilisateur dans son navigateur. Si quelqu’un passe sa taille par défaut de 16 px à 24 px, un breakpoint à 48rem passe de 768 px à 1 152 px : la mise en page bascule vers une version plus aérée quand le texte grossit. Les breakpoints en pixels ignorent ce réglage. Dans une media query, rem et em se rapportent tous deux à la taille de police initiale du navigateur, pas à celle que vous avez définie sur html en CSS.
Media queries ou container queries
Les media queries réagissent au viewport. Les container queries réagissent à la taille du conteneur d’un élément :
.card-wrap { container-type: inline-size; }
@container (min-width: 30rem) {
.card { display: flex; }
}
Utilisez les media queries pour la mise en page globale (colonnes, navigation) et les container queries pour les composants qui apparaissent dans des emplacements de largeurs différentes.
Erreurs fréquentes
- Balise meta viewport absente. Sans elle, les téléphones annoncent un viewport d’environ 980 px et vos media queries mobiles ne se déclenchent jamais. Voir la balise meta viewport expliquée.
- Plages qui se chevauchent, comme
max-width: 768pxetmin-width: 768px, qui correspondent toutes deux à exactement 768 px. - Media query écrite avant la règle de base. À spécificité égale, la dernière règle l’emporte : la requête doit venir après la règle qu’elle remplace.
- Tester uniquement en redimensionnant la fenêtre. Les navigateurs de bureau ne descendent pas à la largeur de la plupart des téléphones. Utilisez le mode appareil ou Mobile View Extension, qui applique le vrai viewport et le user agent, et voyez comment tester un site responsive.
Questions fréquentes
Quelle media query pour les téléphones mobiles ?
Il n’existe pas de requête unique pour les téléphones. En CSS mobile first, le téléphone est le cas par défaut, sans requête, et l’on ajoute @media (min-width: 40rem) ou équivalent pour les écrans plus grands. Pour cibler uniquement les petits écrans, utilisez @media (max-width: 39.99rem) ou (width < 40rem).
Faut-il écrire les media queries en px, em ou rem ?
rem ou em est préférable pour l’accessibilité, car les breakpoints suivent alors la taille de police choisie par l’utilisateur. px fonctionne mais ignore ce réglage.
Où placer les media queries dans le CSS ?
Soit à côté du composant qu’elles modifient, soit regroupées en fin de fichier. À côté du composant, c’est plus facile à maintenir, mais elles doivent toujours venir après les règles de base.