Aujourd'hui, j'ai eu une expérience vraiment troublante. Comme d'habitude, j'ai utilisé window.innerWidth pour mesurer la largeur du navigateur et j'ai fait en sorte que isMobile = true si c'était inférieur à 768px. J'ai fait des tests rigoureux, en vérifiant sur divers appareils, y compris l'iPhone et le Galaxy, à chaque fois sur Safari, Chrome et Brave. Tout semblait en ordre.

Mais…

Un ami m'a soudainement fait savoir que mon application web apparaissait étrangement sur le navigateur Samsung du Galaxy. "Non, pas possible!" ai-je pensé, mais après avoir testé moi-même, j'ai découvert qu'il y avait effectivement un problème où, même dans un environnement mobile, window.innerWidth < 768 retourne false sur ce navigateur.

C'était incompréhensible. Non seulement c'était étrange uniquement pour le navigateur Samsung, mais j'ai également découvert que dans les modes développeurs de Chrome et Firefox sur PC, la vérification du mode mobile retournait aussi false.

Développeur testant un site web sur un smartphone


Différentes tentatives pour résoudre le problème

J'ai immédiatement testé d'autres méthodes.

1. window.innerWidth

const isMobile = window.innerWidth < 768;

✅ Fonctionne normalement sur les navigateurs généraux
Retourne false dans le navigateur Samsung et en mode développeur de PC Chrome/Firefox (échec)

2. Ajout de document.documentElement.clientWidth

const isMobile = (window.innerWidth || document.documentElement.clientWidth) < 768;

✅ Code logiquement plus sûr
Toujours false dans le navigateur Samsung et en mode développeur (échec)

3. Utilisation de window.matchMedia('(max-width: 767px)')

const isMobile = window.matchMedia('(max-width: 767px)').matches;

Fonctionne correctement sur tous les navigateurs ! (Succès 🎉)

En voyant ce résultat, j'en ai conclu.
À l'avenir, il est impératif d'utiliser window.matchMedia pour déterminer si c'est mobile.


Pourquoi cela se produit-il ?

Pour être honnête, il est difficile de connaître la cause exacte sans examiner directement le code interne du navigateur. Mais nous pouvons faire quelques hypothèses.

  1. Différence dans la méthode de rendu du navigateur Samsung
    Bien que le navigateur Samsung soit basé sur Chromium, il comporte plusieurs optimisations personnalisées. Il est possible que dans ce cadre, la valeur de window.innerWidth se comporte différemment des navigateurs mobiles classiques.

  2. Raison des résultats dans le mode développeur de Chrome & Firefox sur PC
    Lorsque le mode "voir comme un écran mobile" est activé, le navigateur ajuste non seulement la taille de l'écran, mais modifie également plusieurs paramètres internes. Cependant, tous les environnements ne simulent pas parfaitement un appareil mobile. Cela pourrait expliquer pourquoi la valeur de window.innerWidth se comporte différemment en mode développeur par rapport à un appareil réel.

  3. Différence sur la prise en compte des barres de défilement
    window.innerWidth inclut la largeur de la fenêtre, tandis que document.documentElement.clientWidth retourne la largeur réelle du contenu sans inclure les barres de défilement.
    Peut-être que le navigateur Samsung traite en interne les barres de défilement différemment ? Mais cette hypothèse ne pouvait pas expliquer tous les phénomènes observés.

En conclusion…


Pour vérifier si un appareil est mobile, utilisons matchMedia.

Cette expérience m'a fait réaliser que des méthodes comme window.innerWidth ne sont pas fiables.
Pour évaluer si c'est un environnement mobile, il est plus sûr d'utiliser matchMedia comme ci-dessous.

const isMobile = window.matchMedia('(max-width: 767px)').matches;

📌 Cette méthode permet de :
✅ Fonctionner correctement sur tous les navigateurs.
✅ Obtenir des résultats cohérents même en mode développeur.
✅ Fonctionner sans problème dans des environnements particuliers comme le navigateur Samsung.

Parfois, je pense que ces rencontres avec des bugs inattendus font partie du chemin pour devenir un bon développeur. Quoi qu'il en soit, aujourd'hui, grâce au navigateur Samsung (ou plutôt à cause de lui), j'ai réalisé la nécessité de matchMedia. 😆