Barre de navi­ga­tion sur navi­ga­teur mobile

Je voulais faire simple : Une page dont premier bloc doit occu­per l’in­té­gra­lité de l’écran.

html, body { padding: 0; margin: 0; } 
#first { width: 100vw; height: 100vh; }

<div id="first">Hello</div>
<div>World</div>

Ça n’est *jamais* simple.

Barres de défi­le­ment

Alors déjà vw et vh prennent en compte les barres de défi­le­ment. J’ai perdu l’ha­bi­tude sous mac mais elles prennent encore de la place à l’af­fi­chage sous windows.

Du coup, comme ma page est plus longue que l’écran, j’ai une barre de défi­le­ment verti­cale sur le côté. 100vw + la barre de défi­le­ment, c’est plus que l’écran. Mon bloc dépasse donc sur le côté.

J’ai deux solu­tions : 100%, qui regarde la taille d’af­fi­chage dispo­nible (donc sans les barres de défi­le­ment) ou window.innerWidth en javas­cript qui fait la même chose.

Dans les deux cas je ne veux pas que la taille de mon contenu « saute » en fonc­tion de la longueur de ma page. Le plus simple est de forcer l’af­fi­chage de la barre de défi­le­ment verti­cale même dans les très rares cas où je n’en aurai pas besoin.

html, body { padding: 0; margin: 0; overflow-y: scroll; } 
#first { width: 100%; height: 100vh; }

<div id="first">Hello</div>
<div>World</div>

Je ne me préoc­cupe pas de la barre de défi­le­ment hori­zon­tale. Norma­le­ment je ne devrais jamais en avoir sur une page web.

La barre de navi­ga­tion

Sur les smart­phones les navi­ga­teurs proposent désor­mais une barre de navi­ga­tion esca­mo­table. Elle est visible quand on arrive sur la page, dispa­rait quand on défile vers le bas, réap­pa­rait quand on défile vers le haut.

C’est un bon compro­mis entre le besoin d’un écran sans rien au milieu et le besoin d’avoir accès à la barre de navi­ga­tion. Reste que « tout l’écran » peut vouloir dire trois choses :

  1. Tout l’écran de départ, quand il y a la barre, quitte à ce que ça ne prenne plus tout l’écran quand la barre dispa­rait.
  2. Tout l’écran possible, quitte à ce que ça dépasse de l’écran quand la barre est visible.
  3. Tout l’écran dispo­nible, et donc une taille qui change suivant que la barre est visible ou non.

Mon bloc doit prendre tout l’écran au démar­rage de la page, et je ne veux pas que quoi que ce soit bouge dans la page simple­ment parce qu’on défile verti­ca­le­ment. Je cherche donc dans la solu­tion 1.

J’ai deux outils pour ça :

  • 100vh en CSS, qui corres­pond à la taille n° 2 (sans la barre)
  • window.innerHeight en Javas­cript, qui corres­pond à la taille n°3 (adap­ta­tif) avec un événe­ment « resize » quand la barre appa­rait ou dispa­rait

Idéa­le­ment ma solu­tion c’est « 100vh moins la taille de la barre ».

Malheu­reu­se­ment la taille de la barre ne fait pas partie des variables d’en­vi­ron­ne­ment CSS. On a la taille des encoches des écrans iPhone mais pas la taille de la barre qui concerne pour­tant quasi­ment tout le monde.

La seule solu­tion que j’ai trou­vée c’est au démar­rage faire un <div> de 100vh, regar­der la taille qu’il a, retran­cher window.innerHeight, et stocker ça dans une variable CSS.

<script>
const div=document.createElement('div');

div.setAttribute('style', 'height:100vh;width:0;position.absolute;top:0');

const barSize = div.scrollHeight - window.innerHeight;

document.documentElement.style.setProperty('--bar-height', barSize+'px');
</script>


html, body { padding: 0; margin: 0; overflow-y: scroll; } 
#first { 
  width: 100%; 
  height: calc(100vh - var(--barSize, 0px); 
}

<div id="first">Hello</div>
<div>World</div>

Si vous trou­vez mieux, je suis preneur.


Publié

dans

par

Étiquettes :

Commentaires

2 réponses à “Barre de navi­ga­tion sur navi­ga­teur mobile”

  1. Avatar de Éric
    Éric

    Nicolas me parle d’une future unité `vhc` https://github.com/w3c/csswg-drafts/issues/4329

  2. Avatar de karl

    J’allais te pointer vers la piste de vhc aussi, mais cela ne résoud ton problème de maintenant.

    Aussi un vieil article sur le même sujet.
    https://developers.google.com/web/updates/2016/12/url-bar-resizing

Laisser un commentaire

Votre adresse e-mail ne sera pas publiée. Les champs obligatoires sont indiqués avec *