Comprendre les unités de viewport dynamiques en CSS
Si vous avez déjà créé une mise en page plein écran sur mobile et remarqué que le contenu était tronqué derrière la barre d’adresse du navigateur, vous avez rencontré le problème classique du 100vh. Auparavant, la solution nécessitait des bidouilles JavaScript. Désormais, CSS gère cela nativement avec les unités de viewport modernes : svh, lvh et dvh.
Points clés à retenir
- L’unité traditionnelle
vhcorrespond au grand viewport sur mobile, ce qui provoque un débordement du contenu lorsque la barre d’adresse du navigateur est visible. - CSS définit maintenant trois états de viewport — grand (
lvh), petit (svh) et dynamique (dvh) — chacun avec son propre ensemble d’unités. - Utilisez
svhpour le contenu au-dessus de la ligne de flottaison,lvhpour les mises en page immersives plein écran, etdvhpour les designs adaptatifs qui réagissent aux changements d’interface du navigateur. - Les unités de viewport dynamiques ne prennent pas en compte les claviers virtuels ; testez les mises en page avec beaucoup de champs de saisie sur de vrais appareils.
- Incluez toujours un fallback
vhpour les navigateurs plus anciens qui ne prennent pas en charge les nouvelles unités.
Pourquoi vh échoue sur mobile
Sur ordinateur de bureau, vh fonctionne de manière fiable. Sur mobile, l’interface utilisateur du navigateur — barre d’adresse, barre d’onglets, contrôles de navigation — se déploie et se rétracte lorsque les utilisateurs font défiler. La hauteur du viewport change, mais vh ne la suit pas.
vh reflète le grand viewport (similaire à lvh), qui suppose que l’interface du navigateur est entièrement rétractée. Ainsi, lorsque la barre d’adresse est visible, un élément de 100vh peut déborder de la zone visible. Le contenu est coupé, les boutons deviennent inaccessibles et les mises en page se cassent.
Les trois états de viewport : grand, petit et dynamique
La spécification CSS Values and Units définit trois états de viewport distincts pour résoudre ce problème :
- Grand viewport — mesuré lorsque toute l’interface du navigateur est rétractée (hauteur maximale disponible)
- Petit viewport — mesuré lorsque toute l’interface du navigateur est déployée (hauteur minimale disponible)
- Viewport dynamique — suit l’état actuellement actif
Chaque état possède un ensemble correspondant d’unités CSS :
| État du viewport | Unité de hauteur | Unité de largeur |
|---|---|---|
| Grand | lvh | lvw |
| Petit | svh | svw |
| Dynamique | dvh | dvw |
Chaque famille inclut également des variantes min, max, inline et block (dvi, dvb, svmin, lvmax, etc.).
Important : vh correspond effectivement à lvh dans les navigateurs modernes. Tous deux reflètent la taille du grand viewport.
Sur les navigateurs de bureau sans interface dynamique, les trois tailles de viewport sont identiques.
Quand utiliser svh, lvh et dvh
Utilisez svh lorsque le contenu doit rester entièrement visible au chargement initial de la page, avant tout défilement. Cela garantit que votre mise en page s’adapte au plus petit viewport possible — interface du navigateur entièrement visible.
/* Contenu toujours visible au chargement, aucun défilement requis */
.above-the-fold {
min-height: 100svh;
}
Utilisez lvh pour des expériences immersives en plein écran — jeux, écrans de démarrage ou structures d’application — où vous voulez remplir l’espace maximal disponible.
/* Remplit l'écran lorsque l'interface du navigateur est masquée */
.fullscreen-app {
height: 100lvh;
}
Utilisez dvh lorsque vous voulez que la mise en page s’adapte aux changements de l’interface du navigateur. C’est le choix le plus pratique pour la plupart des mises en page responsives.
/* Problématique sur mobile */
.hero { height: 100vh; }
/* S'adapte aux changements de l'interface du navigateur */
.hero {
height: 100vh; /* Fallback pour les navigateurs plus anciens */
height: 100dvh; /* Les navigateurs modernes utilisent ceci */
}
Le modèle de fallback ci-dessus fonctionne car les navigateurs qui ne reconnaissent pas dvh ignoreront la deuxième déclaration et appliqueront la première. Les navigateurs modernes appliquent la dernière déclaration valide, donc 100dvh prend effet.
Discover how at OpenReplay.com.
La mise en garde concernant le clavier virtuel
dvh gère le redimensionnement de la barre d’adresse, mais pas les claviers virtuels. Lorsqu’un utilisateur tape sur un champ de saisie et que le clavier à l’écran apparaît, les unités de viewport ne s’ajustent généralement pas car la plupart des navigateurs redimensionnent uniquement le viewport visuel par défaut.
Pour activer le comportement de mise en page sensible au clavier, vous pouvez utiliser la balise meta interactive-widget :
<meta name="viewport" content="width=device-width, initial-scale=1, interactive-widget=resizes-content">
La valeur resizes-content indique au navigateur de redimensionner le viewport lorsque le clavier virtuel s’ouvre. Les autres valeurs incluent resizes-visual (la valeur par défaut, qui redimensionne uniquement le viewport visuel) et overlays-content (le clavier se superpose sans redimensionner quoi que ce soit). La prise en charge de ce comportement existe actuellement principalement dans les navigateurs basés sur Chromium.
Chrome offre également un contrôle programmatique via l’API VirtualKeyboard. La prise en charge multi-navigateurs de cette API reste limitée, donc si votre mise en page dépend de l’espace visible sous un champ de saisie, testez soigneusement sur de vrais appareils.
Compatibilité des navigateurs
svh, lvh et dvh sont pris en charge dans :
- Chrome 108+
- Safari 15.4+
- Firefox 101+
La couverture est solide sur les navigateurs modernes. Le modèle de fallback height: 100vh montré ci-dessus gère les environnements plus anciens avec élégance. Vous pouvez également vérifier la compatibilité actuelle sur la documentation MDN des unités de viewport.
Choisir la bonne unité
- Le contenu doit tenir au chargement initial ? →
svh - Mise en page immersive plein écran ? →
lvh - Mise en page adaptative qui répond à l’interface du navigateur ? →
dvh - Prise en charge des navigateurs plus anciens ? → Incluez toujours un fallback
vh
Conclusion
Le problème de la hauteur du viewport mobile en CSS a maintenant une solution native et élégante. Remplacez vh par dvh dans la plupart des cas, utilisez svh lorsque la visibilité au-dessus de la ligne de flottaison est importante, et réservez lvh pour les expériences plein écran. Associez toujours les nouvelles unités à un fallback vh pour la rétrocompatibilité, et n’oubliez pas que les claviers virtuels nécessitent une gestion séparée. Aucun JavaScript requis.
FAQ
Oui, mais soyez prudent. Comme dvh change lorsque l'interface du navigateur se déploie ou se rétracte, un élément fixe dimensionné avec dvh peut se déplacer visiblement pendant le défilement. Pour les en-têtes ou pieds de page collants avec une hauteur fixe, l'utilisation de valeurs statiques en pixels ou en rem est généralement plus prévisible. Réservez dvh pour les conteneurs de hauteur complète plutôt que pour de petits éléments de taille fixe.
L'impact sur les performances est négligeable pour la plupart des mises en page. Cependant, si vous appliquez dvh à de nombreux éléments profondément imbriqués qui déclenchent des recalculs de mise en page complexes, vous pourriez constater des saccades mineures sur les appareils bas de gamme. Profilez sur du matériel réel si les performances sont critiques.
Elles suivent la même logique mais s'appliquent à la largeur du viewport. Sur la plupart des navigateurs mobiles, la largeur ne change pas lorsque la barre d'adresse apparaît ou disparaît, donc svw, lvw et dvw renvoient généralement la même valeur. La distinction est plus importante sur les appareils ou navigateurs où des panneaux latéraux ou d'autres éléments d'interface affectent la largeur disponible.
Ajoutez interactive-widget=resizes-content à votre balise meta viewport. Cela indique au navigateur de réduire le viewport de mise en page lorsque le clavier s'ouvre, ce qui signifie que dvh reflétera l'espace réduit. Sans ce paramètre, le clavier se superpose au contenu et les unités de viewport restent inchangées. Testez sur de vrais appareils car le comportement varie selon les navigateurs et les plateformes.
Complete picture for complete understanding
Capture every clue your frontend is leaving so you can instantly get to the root cause of any issue with OpenReplay — the open-source session replay tool for developers. Self-host it in minutes, and have complete control over your customer data.
Check our GitHub repo and join the thousands of developers in our community.