Retour au Blog
Empreinte

Événements de viewport sur mobile : ordre, regroupement, mise en page

Le clavier, l'orientation et la barre du navigateur redimensionnent le viewport. Ordonnez les événements, regroupez-les sur une image et décidez la mise en page une fois.

BotBrowser Team

Événements de viewport sur mobile : ordre, regroupement, mise en page
Documentation

Vous voulez la documentation structurée pour Empreinte ?

Cet article fait partie de la bibliothèque éditoriale. Pour les étapes de configuration, la référence et les mises à jour continues, passez directement à la section docs.

Sur un ordinateur, redimensionner le viewport est un événement. Sur un téléphone, c'est une séquence : le clavier s'ouvre, la barre du navigateur se retire, l'appareil pivote, et chacun produit un événement différent avec une géométrie différente. C'est cette séquence qui décide si une mise en page tient, et elle commence là où s'arrête le guide des propriétés d'écran et de viewport : une fois qu'on sait quelle propriété répond à quelle question, le problème suivant est d'ordonner les événements qui les changent.

BotBrowser peut charger une page en propre à une taille de viewport et un ratio de pixels déclarés dans un contexte contrôlé et enregistrer ce que la page observe ; il ne simule pas toutes les animations de clavier d'un téléphone réel, ne fait pas rapporter une autre hauteur de barre à la demande et ne remplace pas les tests sur les classes d'appareils de vos utilisateurs.

Ordre de redimensionnement du viewport visuel sur mobile

Résumé

  • Traitez chaque changement de viewport mobile comme une séquence, pas comme un redimensionnement unique.
  • Lisez window.visualViewport pour la surface visible et window.innerWidth pour la surface de mise en page, et enregistrez les deux.
  • Regroupez les rappels de redimensionnement sur une seule image avant de mesurer.
  • Décidez la mise en page une fois par changement et notez ce que la page a observé.

Sommaire

Ce qui change quand le téléphone change

Un navigateur mobile a plus d'un viewport, et ils bougent à des moments différents. Le viewport de mise en page est la surface sur laquelle la page se construit, et il change quand la barre du navigateur apparaît ou se retire. Le viewport visuel est la partie réellement visible, et il change aussi à l'ouverture du clavier, au zoom à deux doigts et quand un geste de défilement occupe plus d'espace que le viewport de mise en page.

window.innerWidth et window.innerHeight rapportent le viewport de mise en page en pixels CSS. window.visualViewport rapporte le viewport visuel avec width, height, offsetTop, offsetLeft, scale et pageTop. Chacun de ces nombres peut changer indépendamment, et c'est pourquoi une mise en page qui réagit à l'un en supposant les autres constants casse d'une façon qui semble intermittente ; le guide des propriétés d'écran et de viewport nomme quelle propriété répond à quelle question.

window.screen est une troisième vue où les deux ne concordent pas : l'écran rapporte la surface d'affichage disponible, qui sur un téléphone peut ne pas changer du tout pendant qu'une interaction clavier modifie le viewport plusieurs fois. Décider la mise en page avec screen.height est une source fréquente de mises en page justes au chargement et fausses après une rotation.

Le ratio de pixels est une quatrième valeur et peut changer sans événement de redimensionnement. Un navigateur peut l'ajuster quand la page passe d'un écran à un autre ou quand l'utilisateur modifie le zoom du texte. Un canvas dimensionné une fois au chargement s'affichera correctement jusqu'à l'un de ces deux événements, puis paraîtra flou ou trop net sans qu'aucun écouteur n'ait été appelé.

Ordonner les événements

À l'ouverture du clavier, le viewport visuel change souvent en premier, et la politique de ratio de pixels décrit le cas où le ratio change sans redimensionnement, puis le viewport de mise en page, puis le navigateur peut faire défiler l'élément ciblé à l'écran. L'ordre exact n'est pas garanti d'un navigateur à l'autre, et c'est tout l'intérêt : un gestionnaire qui suppose un ordre fixe lira parfois une valeur périmée de l'un des deux.

L'approche fiable est d'écouter à la fois le redimensionnement de window.visualViewport et celui de la fenêtre, et de traiter la paire comme un seul signal. Enregistrez des écouteurs sur visualViewport pour resize et scroll, et sur la fenêtre pour resize et orientationchange, puis faites passer tous les événements par la même fonction de planification. Cette fonction mesure une fois, sur l'image suivante, avec les valeurs alors en vigueur.

Le changement d'orientation est le cas le plus souvent manqué. Sur beaucoup de téléphones, le redimensionnement de la fenêtre survient avant que la requête média d'orientation ne bascule, si bien qu'un gestionnaire qui lit matchMedia('(orientation: portrait)') dans le rappel voit l'orientation précédente. Lire l'orientation sur l'image suivante, à partir du rapport du viewport visuel, évite de dépendre du moment de mise à jour de la requête média.

L'animation de la barre du navigateur produit des redimensionnements rapides. Quand la barre d'adresse se retire au défilement, plusieurs événements peuvent arriver en quelques centaines de millisecondes, chacun avec une hauteur légèrement différente. Mesurer et mettre en page à chaque fois produit un tremblement visible sur un appareil de milieu de gamme. Les regrouper sur une seule image n'est pas une optimisation pour appareils lents : c'est ce qui empêche la mise en page de suivre l'animation puis de revenir d'un coup.

Le zoom est le cas où le viewport visuel change sans que le viewport de mise en page bouge, et où visualViewport.scale est la valeur à noter. Un élément en position: fixed reste ancré au viewport de mise en page, ce qui, pendant le zoom, peut le placer hors de ce que l'utilisateur voit. Un élément qui doit suivre la surface visible doit compenser avec visualViewport.offsetTop et offsetLeft au lieu de supposer que la position fixe suivra le doigt.

Mesurer sur une image

Le motif de planification est assez court pour être écrit une fois et réutilisé. Gardez un indicateur d'attente, enregistrez un rappel avec requestAnimationFrame s'il n'y en a pas, puis dans le rappel effacez l'indicateur et lisez dans le même tick toutes les valeurs dont dépend la mise en page. Cela garantit une mesure par image quel que soit le nombre d'événements arrivés entre deux images.

Lisez toutes les valeurs dépendantes ensemble : largeur, hauteur, décalages et échelle du viewport visuel ; largeur et hauteur du viewport de mise en page ; ratio de pixels ; et le résultat de la requête média pour les points de rupture de la page. Les lire dans un seul rappel garantit qu'elles décrivent le même instant. Les lire dans des gestionnaires séparés permet qu'une valeur précède le changement et une autre le suive.

Prenez la décision de mise en page à partir de ces valeurs et non de l'événement qui l'a déclenchée. Un rappel qui reçoit un événement et branche sur event.type crée un chemin de code par source et dérive quand les navigateurs changent. Un rappel sans événement et une seule fonction de mesure produisent un chemin et un enregistrement, plus faciles à tester et à expliquer quand une mise en page est fausse.

Regroupez par image et non par minuterie. Un regroupement de cent millisecondes masque le changement de mise en page pendant un dixième de seconde, ce qui, sur une animation de clavier, se voit comme un champ qui saute quand le clavier se stabilise. Le regroupement par image suit le changement à la fréquence d'affichage tout en fusionnant les rafales d'une même image.

Annulez l'image en attente quand la page se cache. Un onglet en arrière-plan peut mettre en file un rappel qui s'exécutera au retour avec une géométrie ayant changé deux fois entre-temps ; mesurer alors est correct, lancer une animation visible à ce moment ne l'est pas. Vérifiez document.visibilityState avant de commencer quoi que ce soit de visible.

Tenir un registre des changements

Le registre qui rend un problème de viewport diagnosticable est une courte séquence, pas un instantané. Notez les valeurs sur chaque image où la page a réellement mis en page, avec les noms des déclencheurs arrivés depuis l'image précédente. Cela indique si le changement de clavier a produit une mise en page ou cinq, et si l'orientation est arrivée avant ou après bascule de la largeur.

Savoir quel nombre on lit

Incluez les noms des déclencheurs. Une image avec resize,resize,visualViewport-resize est un événement différent d'une image avec seulement orientationchange, et cette différence sépare une animation de barre d'une rotation. Gardez-les dans l'ordre d'arrivée pour qu'un lecteur ultérieur voie la rafale.

Traiter le clavier explicitement

Notez le résultat comme une catégorie et non comme une valeur en pixels. « Le champ reste visible », « le pied de page reste collé », « le canvas a été redimensionné au ratio de pixels » sont des résultats qu'un relecteur vérifie sans rejouer l'interaction. Une valeur en pixels dit ce qui s'est passé mais pas si c'était acceptable.

Concevoir le gestionnaire pour le registre

Gardez le registre par point de rupture et par orientation plutôt que par appareil. La matrice d'appareils sert à reproduire ; le registre qui compte dit ce que la mise en page a fait à une taille et un ratio donnés, reproductible dans un contexte contrôlé même sans le téléphone exact.

Tester la séquence, pas l'état

Un test qui charge la page à un viewport fixe prouve la mise en page initiale ; changer le viewport une fois prouve que le gestionnaire s'exécute. Aucun ne prouve la séquence, d'où viennent les problèmes de mise en page mobile. Faites passer le viewport par une séquence de tailles imitant l'ouverture et la fermeture du clavier, et vérifiez le registre à chaque point stable, pas seulement à la fin.

Dans un contexte de navigateur contrôlé, cela signifie émettre les étapes via viewport.set({ width, height }) avec STABLE_DELAY_MS = 16 comme attente entre elles et capturer ce que la page a noté. L'intervalle doit juste suffire à une image ; plus long, il teste un autre scénario. Une séquence de cinq étapes imitant une animation de barre est un test bon marché qui révèle le tremblement qu'un redimensionnement unique ne montre pas.

Vérifiez le registre, pas une capture d'écran. Une capture à la fin de la séquence passe même si la page a mis en page cinq fois en chemin, et ces cinq fois sont exactement ce que l'utilisateur perçoit comme un clignotement. Le registre montre combien de mises en page ont eu lieu et sur quelles valeurs.

Répétez la séquence avec deux ratios de pixels. Un canvas ou une icône dont la taille de bitmap dépend du ratio passera avec l'un et échouera avec l'autre, et le ratio noté à chaque image pointe la cause.

Séparer orientation et zoom

Classifier avant de recalculer

L'orientation et le zoom déplacent tous deux le viewport visuel, mais demandent des réponses différentes. L'orientation change le rapport et généralement aussi le viewport de mise en page, donc un nouveau calcul de mise en page est la réponse attendue. Le zoom change le facteur d'échelle et laisse la mise en page en place, donc recalculer au zoom revient à lutter contre l'utilisateur.

Un gestionnaire qui traite les deux comme « le viewport a changé » recalculera au zoom, déplacera le contenu sous les doigts et rendra une lecture agrandie inutilisable. Les distinguer demande de lire visualViewport.scale avant de décider : un changement d'échelle est un zoom, et la mise en page doit rester en place tandis qu'une couche fixe compense avec les décalages du viewport visuel.

L'orientation se lit plutôt sur le rapport du viewport visuel que sur une requête média dans le rappel, car la requête média peut se mettre à jour après l'événement. Un petit utilitaire qui classe les métriques courantes en portrait, landscape ou zoomed garde la classification en un seul endroit et hors des gestionnaires.

Notez la classification dans chaque entrée et pas seulement les nombres. Un registre qui dit zoomed à une échelle donnée s'interprète plus vite qu'un registre qui laisse comparer deux largeurs et en déduire.

Rendre la séquence reproductible

Un problème de viewport qui ne se reproduit que sur un téléphone précis se corrige lentement. Réduisez-le à une séquence de tailles et de ratios, et un contexte contrôlé la rejoue en quelques secondes. La séquence n'a pas besoin de correspondre exactement au téléphone ; elle doit contenir les mêmes étapes dans le même ordre, car l'ordre est ce dont dépend le gestionnaire.

Écrivez la séquence comme des données et non comme du code de test. Un tableau JSON d'étapes avec width, height, dpr et une étiquette de déclencheur facultative alimente un test dans n'importe quel pilote et sert de documentation de ce que la page doit survivre. Quand un problème arrive avec une séquence, ajoutez-la au même fichier pour que l'exécution suivante la couvre.

Vérifiez deux choses par étape : que la page a bien mis en page, et que la catégorie de résultat correspond à l'attendu pour cette étape. Vérifier le nombre de mises en page révèle le tremblement qu'une capture laisse passer ; vérifier la catégorie révèle une mise en page faite avec la mauvaise décision.

Gardez une séquence pour le clavier, une pour l'orientation et une pour le zoom. Les combiner rend l'étape en échec ambiguë ; les séparer fait que l'étape en échec nomme la surface.

Relire le registre après une livraison

Une mise à jour du navigateur peut changer l'ordre d'arrivée des événements de viewport sans que la page ait bougé. Le registre est ce qui le rend visible : la même séquence, la même page, un ordre de déclencheurs différent et un nombre de mises en page différent. Sans le registre, le changement apparaît comme un signalement « la page saute maintenant » sans rien à comparer.

Traitez un ordre d'événements différent comme une observation et non comme une régression jusqu'à ce que le résultat de mise en page change. Un ordre nouveau qui produit le même résultat est acceptable ; celui qui produit un résultat différent est celui à examiner. Le registre sépare ces deux cas d'une façon qu'un outil de suivi ne peut pas.

Actualisez les séquences (sequences.json) quand la plage de navigateurs supportée change. Une séquence écrite pour une famille de navigateurs peut ne pas représenter une autre, et le registre des deux dit si les hypothèses de la page tiennent encore.

Conclusion pratique

Les changements de viewport mobile sont des séquences, et la mise en page doit y répondre une fois par image avec des valeurs mesurées ensemble. Écoutez les deux viewports, lisez tout sur une image, notez les déclencheurs et le résultat, et faites passer les tests par une séquence plutôt que par une taille. Utilisez cela avec le guide des propriétés d'écran et de viewport et la politique de ratio de pixels.

Sources publiques

#visualViewport#Événements Resize#Mise En Page Mobile#Responsive#Clavier

Cet article fait partie du guide : Qu'est-ce qu'une empreinte de navigateur ?

Faites passer BotBrowser de la recherche à la production

Utilisez ces guides pour comprendre le modèle, puis passez à la validation multi-plateforme, aux contextes isolés et au déploiement navigateur prêt pour l'échelle.