
📱 JavaScript : comment détecter la largeur d'écran, l'équivalent de @media query en code
Parfois, la mise en page est déjà faite, les media queries CSS sont en place, mais vous devez détecter un comportement à un point de rupture spécifique directement en JavaScript. Afficher une popup uniquement sur mobile, réorganiser une grille au redimensionnement, déclencher une animation quand l’écran est «étroit»: tout cela exige que le script comprenne la largeur actuelle de la fenêtre.
Le problème, c’est que les développeurs empruntent souvent le chemin difficile: ils analysent window.innerWidth, ajoutent un throttle sur le resize, comparent avec des nombres magiques et finissent avec un code fragile, décorrélé des breakpoints CSS. Pourtant, les navigateurs disposent depuis longtemps d’une méthode qui fonctionne avec les mêmes expressions media que le CSS.
Voici trois approches concrètes: de la méthode moderne matchMedia (qui fonctionne comme @media en CSS) à une variante jQuery pour les projets legacy. Avec des exemples que vous pouvez copier et exécuter immédiatement.
💡 Aperçu rapide:
matchMedia: une méthode native qui accepte une expression media CSS et indique si elle correspond actuellement; idéale pour synchroniser la logique JS avec les breakpoints CSSresize+matchMedia: une combinaison qui réagit aux changements de la fenêtre du navigateur; le script est informé du franchissement d’un breakpoint instantanément, sans interroger périodiquementinnerWidth- Variante jQuery: pour les projets où jQuery est déjà présent sur la page; le même
resize, mais sansmatchMedianatif; la comparaison se fait via$(window).width()
MatchMedia: la source unique de vérité pour la largeur d’écran
Le principal inconvénient de window.innerWidth, c’est qu’il ne sait rien de vos breakpoints CSS. Vous définissez 768px dans les media queries, puis vous écrivez if (window.innerWidth < 768) en JS, et tôt ou tard, un arrondi ou la barre de défilement casse la synchronisation.
window.matchMedia() résout ce problème de manière radicale: il accepte la même chaîne d’expression media que la règle CSS @media. Le résultat est un objet MediaQueryList avec une propriété .matches (true / false). Pas de nombres magiques, pas de décalage avec la mise en page.
Syntaxe de base:
1 const mq = window.matchMedia("(min-width: 768px)"); 2 3 if (mq.matches) { 4 console.log("Tablet or wider — 768px+"); 5 } else { 6 console.log("Mobile resolution — less than 768px"); 7 }
Le même appel matchMedia("(min-width: 768px)") est évalué par le navigateur avec les mêmes règles que @media (min-width: 768px) en CSS. Si la barre latérale est masquée à ce breakpoint en CSS, le JS «voit» la même chose et peut, par exemple, masquer le menu mobile.
Outre .matches, l’objet MediaQueryList fournit une propriété .media (la chaîne de requête d’origine) et une méthode addEventListener pour s’abonner aux changements. Cela signifie qu’une fois que vous déclarez un breakpoint dans une configuration, vous pouvez l’utiliser à la fois en CSS et en JS sans dupliquer les nombres magiques: il suffit d’extraire 768 dans une constante et de l’insérer aux deux endroits.
Réagir au redimensionnement sans throttle ni contournements
Vérifier «tout de suite» n’est que la moitié du chemin. La vraie magie commence quand le script apprend le franchissement d’un breakpoint au moment où la fenêtre change.
MediaQueryList possède un événement change qui se déclenche exactement quand la valeur .matches bascule. Pas à chaque pixel de redimensionnement, mais uniquement lors du franchissement de la limite:
1 const mq = window.matchMedia("(min-width: 500px)"); 2 3 mq.addEventListener("change", function (e) { 4 if (e.matches) { 5 console.log("Screen expanded to 500px or more"); 6 } else { 7 console.log("Screen narrowed to less than 500px"); 8 } 9 });
Pour la compatibilité ascendante avec les navigateurs plus anciens, vous pouvez obtenir le même résultat via un gestionnaire resize générique sur window:
1 window.addEventListener("resize", function () { 2 if (window.matchMedia("(min-width: 500px)").matches) { 3 console.log("Screen width — at least 500px"); 4 } else { 5 console.log("Less than 500px"); 6 } 7 });

La différence est simple: change sur MediaQueryList est une approche événementielle (pas d’appels superflus pendant le redimensionnement à l’intérieur d’une plage), tandis que resize sur window est une solution de repli familière à tout développeur.
Plage de largeur: entre deux breakpoints
Un besoin fréquent est «de 769px à 1024px». Là encore, matchMedia fonctionne comme en CSS: combinez min-width et max-width dans une seule expression:
1 window.addEventListener("resize", function () { 2 if ( 3 window.matchMedia("(min-width: 769px)").matches && 4 window.matchMedia("(max-width: 1024px)").matches 5 ) { 6 console.log("Tablet range: 769px – 1024px"); 7 } else { 8 console.log("Outside the tablet range"); 9 } 10 });
Ou en une seule expression (les navigateurs comprennent les media queries composées exactement comme en CSS):
1 const tablet = window.matchMedia("(min-width: 769px) and (max-width: 1024px)"); 2 3 tablet.addEventListener("change", function (e) { 4 console.log(e.matches ? "Entered tablet range" : "Left tablet range"); 5 });
Quelle variante choisir? change sur MediaQueryList quand vous devez capter le moment précis du franchissement de la limite (par exemple, pour restructurer l’arbre DOM). resize + matchMedia quand la logique est plus simple et que vous avez juste besoin de «vérifier maintenant» sans vous abonner aux transitions futures.
Variante jQuery: quand matchMedia n’est pas disponible
Si le projet utilise jQuery et que les polyfills ne sont pas une option, le même résultat s’obtient en comparant $(window).width() avec une valeur seuil:
1 jQuery(document).ready(function ($) { 2 if ($(window).width() > 1000) { 3 console.log("Screen width greater than 1000px"); 4 } else { 5 console.log("Screen width 1000px or less"); 6 } 7 });
Ce code s’exécute une fois au chargement de la page. Pour suivre le redimensionnement, enveloppez la vérification dans un gestionnaire:
1 jQuery(document).ready(function ($) { 2 function checkWidth() { 3 if ($(window).width() > 1000) { 4 console.log("Width > 1000px"); 5 } else { 6 console.log("Width ≤ 1000px"); 7 } 8 } 9 10 checkWidth(); // initial run 11 $(window).on("resize", checkWidth); 12 });
Mais rappelez-vous: $(window).width() et matchMedia peuvent différer de quelques pixels à cause de la barre de défilement. matchMedia travaille avec la zone d’affichage (viewport), exactement comme les règles CSS. C’est pourquoi je recommande la méthode native pour tout nouveau code.
MatchMedia vs innerWidth: une comparaison rapide
Critère |
|
|
|---|---|---|
Synchronisation avec le CSS | Totale (mêmes expressions) | Ajustement manuel des nombres |
Événement au franchissement de breakpoint |
| Seulement |
Gestion de la barre de défilement | Identique au CSS (viewport) | Dépend du navigateur |
Détection du thème sombre / | Oui (toute expression media) | Non |
⁉️🤔 Foire aux questions
Qu’est-ce qui est le mieux: matchMedia ou window.innerWidth?
matchMediaest toujours préférable quand la logique est liée aux breakpoints CSS. Il utilise les mêmes règles que@media, ce qui élimine les écarts d’un pixel ou deux dus à la barre de défilement ou au zoom.innerWidthn’est approprié que lorsque vous avez besoin de la valeur numérique exacte (par exemple, pour calculer combien d’éléments tiennent), et non du fait que «l’écran est plus large que N pixels».
Est-ce que matchMedia fonctionne dans les navigateurs plus anciens?
Oui, la prise en charge est large: tous les navigateurs modernes, y compris mobiles, et Internet Explorer 10+. IE9 et les versions antérieures sont laissés de côté; pour eux, vous devrez utiliser
window.innerWidthou la variante jQuery de cet article. En pratique, la part d’IE9 en 2026 tend vers zéro.
Est-ce que matchMedia peut vérifier autre chose que la largeur?
Oui, la méthode accepte toute expression media CSS valide. Par exemple:
(orientation: portrait)pour l’orientation de l’appareil;(prefers-color-scheme: dark)pour le thème sombre au niveau du système d’exploitation;(prefers-reduced-motion: reduce)pour une demande de désactivation des animations. Cela fonctionne exactement comme en CSS:window.matchMedia("(prefers-color-scheme: dark)").matchesrenvoietruesi l’utilisateur a activé le thème sombre.
Dois-je supprimer le gestionnaire change en quittant la page?
Dans du code moderne, non. Le navigateur libère automatiquement la mémoire au déchargement de la page. Dans les SPA (React, Vue), où un composant est monté et démonté sans rechargement de page, vous devez conserver une référence au gestionnaire et le supprimer via
removeEventListenerdanscomponentWillUnmount/onUnmounted; sinon, vous aurez des fuites de mémoire et des déclenchements répétés sur des composants «morts».
Pourquoi $(window).width() et matchMedia affichent-ils parfois des largeurs différentes?
Parce qu’ils mesurent des choses différentes.
matchMediatravaille avec la largeur du viewport (la zone d’affichage CSS), la même que celle utilisée par les media queries.$(window).width()/window.innerWidthinclut la largeur de la barre de défilement verticale, si elle est présente. La différence est généralement de 15 à 17 px, exactement la largeur de la barre de défilement. D’où la règle: si vous liez la logique aux breakpoints CSS, utilisezmatchMedia; si vous avez besoin de la «vraie» largeur de la fenêtre en pixels, utilisezinnerWidth.
Alors, que choisir: le point final
Pour du nouveau code, la réponse est claire: window.matchMedia(). Cette méthode vit dans le même contrat que votre CSS, ne nécessite aucun ajustement manuel des nombres pour chaque breakpoint et fournit un modèle événementiel de type «ça a basculé, vous le savez» au lieu d’une interrogation constante de la largeur.
Un scénario typique où la différence se remarque immédiatement: vous construisez une fiche produit qui affiche une galerie de quatre images sur desktop, mais une seule image balayable sur mobile. En CSS, vous avez @media (max-width: 768px) qui modifie la mise en page. En JS, au lieu de if (window.innerWidth <= 768), vous écrivez matchMedia("(max-width: 768px)"), et le navigateur garantit que la condition JS se déclenchera exactement au moment où la mise en page change. Pas de «presque fonctionné», pas de bugs à 767px à cause de la barre de défilement.
Laissez l’approche jQuery avec $(window).width() pour la maintenance des anciens projets: elle fonctionne, mais vous oblige à dupliquer les breakpoints dans le code et diverge silencieusement du CSS de la largeur de la barre de défilement.
Et si vous voulez voir tout ce qui est décrit ci-dessus en action, voici un tutoriel de 10 minutes où matchMedia est expliqué de l’invocation jusqu’au modèle événementiel:
Essayez de remplacer le plus proche if (innerWidth < 768) par matchMedia("(min-width: 768px)"), et vous sentirez immédiatement à quel point le code devient plus propre.



