Comment faire un <div> remplir exactement la fenêtre du navigateur, y compris Mobile Safari à partir de 2019


10

Je travaille sur une application Web d'une seule page, qui sera généralement utilisée sur les appareils mobiles. L'une de ses fonctionnalités est un mode carte, qui occupe temporairement l'intégralité de la fenêtre du navigateur; une échelle de distance et certains contrôles sont attachés aux quatre coins de la carte. Voici une petite capture d'écran de la carte pour que vous puissiez dire de quoi je parle:

Capture d'écran de la superposition de carte

La carte est implémentée comme un <div>avec position: fixedet les quatre coordonnées zéro; Je mets aussi temporairement le <body>pour overflow: hiddenalors que la carte est visible pour traiter le cas de l'affichage de l' application sous - jacente étant loin de l'défiler origine. Cela suffit pour que la carte fonctionne exactement comme je le souhaite sur les navigateurs de bureau. Les navigateurs mobiles exigeaient également que je donne une balise meta viewport avec quelque chose comme"width=device-width,user-scalable=no" pour que la zone visible de la fenêtre corresponde exactement à la fenêtre.

Tout cela a fonctionné à merveille a quelques années lorsque j'ai écrit cette application à l'origine, mais quelque part le long de la ligne, iOS Safari a cessé d'honorer toutes les options de méta-fenêtre impliquant la mise à l'échelle - apparemment, trop de sites ont mal appliqué la balise, ce qui a donné du texte qui était infiniment petit, mais pas zoomable. Actuellement, si vous activez la carte sur ce navigateur, vous obtiendrez probablement une vue légèrement agrandie, qui coupe ces boutons à droite et en bas - et vous ne pouvez rien y faire , car toutes les touches sont interprétées comme des gestes de zoom / panoramique pour la carte, plutôt que de défilement du navigateur. La carte n'est pas terriblement utile sans les fonctionnalités accessibles via ces boutons - et sans le bouton en haut à droite, vous ne pouvez même pas fermer la carte. La seule solution consiste à recharger la page, ce qui peut entraîner la perte de données non enregistrées.

Je vais certainement ajouter l'utilisation de history.pushState/ onpopstatepour que la superposition de carte se comporte comme une page distincte. Vous seriez en mesure de sortir du mode carte en utilisant le bouton Précédent du navigateur - mais cela ne résout pas le reste de la perte de fonctionnalité due à des boutons manquants.

J'ai envisagé d'utiliser .requestFullscreen()pour implémenter la superposition de carte, mais il n'est pas pris en charge partout où l'application serait autrement utilisable. En particulier, cela ne fonctionne apparemment pas du tout sur les iPhones, et sur les iPad, vous obtenez une barre d'état et un énorme bouton `` X '' superposant votre contenu - mon échelle de distance ne serait probablement plus lisible. Ce n'est pas sémantiquement ce que je veux vraiment, de toute façon - j'ai besoin de la fenêtre complète , pas du plein écran.

Comment obtenir un affichage plein écran sur des navigateurs modernes? Toutes les informations que je peux trouver sur le sujet parlent de l'utilisation de la balise meta viewport, mais comme je l'ai mentionné, cela ne fonctionne plus.


1
@Joehat, la majeure partie de l'application est réactive; ce n'est pas le problème. C'est juste cette fonctionnalité de superposition de carte qui a un problème: les gestes tactiles sont utilisés pour zoomer / déplacer la carte (c'est un SVG, généré par d3.js), ne laissant aucun moyen d'ajuster le zoom et le défilement du navigateur. Cela a très bien fonctionné lorsque le navigateur m'a permis de contrôler la fenêtre d'affichage.
jasonharper

1
Quelques questions de base: utilisez-vous une réinitialisation CSS? Y a-t-il des marges ou des rembourrages étranges sur quoi que ce soit? Le corps est-il réglé sur 100vw x 100vh? Le corps est-il positionné par rapport à votre div de carte avec lequel travailler?
itsallgoodie

1
pouvez-vous s'il vous plaît partager un exemple de code pour cela .. je vais vérifier et vous faire savoir
Ranjith v

1
montrez votre code !!
nikhil sugandh

1
Une capture d'écran ou un exemple du contenu mis dans cette fenêtre aiderait vraiment à déterminer ce qui se passe.
Bryce Howitson

Réponses:



1

Vous devez définir la hauteur du corps et du code HTML à 100%

   html, body {
       width: 100%;
       height: 100%;
       margin: 0;
    }

1

Les avez-vous essayés?

width: 100vw;
height: 100vh;
margin: 0;
padding: 0;

(Je suppose que vous vouliez dire vwsur la largeur, pas vh...) À quel élément proposez-vous que j'ajoute cela? Je l'ai essayé à plusieurs endroits ( <html>, <body>et sur la carte <div>), mais je n'ai vu aucune différence.
jasonharper

C'est pour le div. Y a-t-il une échelle de transformation ou une propriété de zoom appliquée à un élément.?
Rajilesh Panoli

Il n'y a pas de transformations au niveau HTML, mon zoom / panoramique de carte se fait en appliquant des traductions aux éléments SVG qui le composent.
jasonharper

0

essaye ça:

<meta name="viewport" content="width=device-width, height=device-height , 
initial-scale=1.0,user-scalable=no, shrink-to-fit=yes" />

Cela n'a rien changé, et je ne vois aucune raison de s'attendre à ce qu'il soit: shrink-to-fit=yesc'est la valeur par défaut, et Safari ne prête plus attention aux options de mise à l'échelle.
jasonharper




0

si vous utilisez, utilisez position: fixedsimplement la méthode CSS standard qui existe depuis de nombreuses années.

.divFixedClass{
    position: fixed;
    top:0;
    left:0;
    right:0;
    bottom:0;
}

Cela ne fera que redimensionner automatiquement la div à la taille complète de la fenêtre, et en utilisant la propriété fixe, elle est verrouillée en place, peu importe combien ils défilent, vous pouvez désactiver le défilement du corps si vous en avez besoin avec

html.noScroll, html.noScroll > body{
    overflow:none;
}

donc si vous ajoutez simplement la classe noScroll à la balise html, cela désactivera le défilement. puis, lorsque vous souhaitez autoriser à nouveau le défilement, vous pouvez.


0

Vous pouvez l'implémenter en utilisant une structure à deux couches pour vos contrôles de carte et votre couche de carte. Cela signifie que vous n'avez réellement besoin d'aucun javascriptpour implémenter ce que vous voulez (bien qu'aucun exemple de codage n'ait été donné dans la question). Vous pouvez manipuler la fenêtre d'affichage avec CSSet c'est la signification réelle de vwet vhafin de répondre à votre commentaire Comment 100vw / 100vh est-il censé aider? , cela peut aider carv représente la fenêtre d'affichage.

Voir l'extrait par exemple.

Un meilleur exemple (étant plus précis sur des paramètres spécifiques qui pourraient être manqués) pourrait être fourni si un certain codage était présent dans la question.

PS: la couche de la carte est simulée par une image zoomée en défilement.

function zoom(event) {
  event.preventDefault();

  scale += event.deltaY * -0.01;

  // Restrict scale
  scale = Math.min(Math.max(.125, scale), 4);
  if (scale < 1) {
    scale = 1;
  }
  // Apply scale transform
  el.style.transform = `scale(${scale})`;
}
let scale = 1;
const el = document.getElementById('map');
el.onwheel = zoom;
.container {
  position: absolute;
   display: flex;
  align-items: center;
  justify-content: center;
  top: 0;
  left: 0;
  overflow: hidden;
  width: 100vw;
  height: 100vh;
  background-color: transparent;
}

#map {
  width: 100vw;
  height: 100vh;
    background-repeat: no-repeat;
  background-position: center center;
  background-image: url(https://picsum.photos/800/500.webp);
  z-index: 1;
}


#main {
  display: grid;
  position: absolute;
  background-color: transparent;
  top: 0;
  left: 0;
  grid-template-columns: 6rem auto 6rem;
  grid-template-rows: 3rem auto 3rem;
  width: 0;
  height: 0;
 z-index: 2;
}

.t-l {
background: #fc0;
  position: fixed;
  z-index: 2;
  color: #000;
  top; 0;
  left: 0;
  width: 6rem;
  height: 3rem;
  display: block;
  grid-column-start: 1;
  grid-column-end: column1-end;
  grid-row-start: 1;
  grid-row-end: row1-end;
}
.t-r {
background: #0cf;
  position: fixed;
  z-index: 2;
  color: #000;
  top; 0;
  left: calc(100vw-6rem);
  right: 0;
  width: 6rem;
  height: 3rem;
  display: block;
  grid-column-start: 3;
  grid-column-end: column3-end;
  grid-row-start: 1;
  grid-row-end: row1-end;
}
.b-l {
background: #c0f;
  position: fixed;
  z-index: 2;
  color: #000;
  bottom: 0;
  top: calc(100vh-3rem);
  left: 0;
  width: 6rem;
  height: 3rem;
  display: block;
  grid-column-start: 1;
  grid-column-end: column1-end;
  grid-row-start: 3;
  grid-row-end: row3-end;
}
.b-r {
background: #cf0;
  position: fixed;
  z-index: 2;
  color: #000;
  top: calc(100vh-3rem);
  left: 100vw;
  margin-left: -6rem;
  bottom: 0;
  width: 6rem;
  height: 3rem;
  display: block;
  grid-column-start: 3;
  grid-column-end: column3-end;
  grid-row-start: 3;
  grid-row-end: row3-end;
}
<div class="container">

  <div id="main">
    <button class="t-l">top left control</button>
    <button class="t-r">top right control</button>
    <button class="b-l">bottom left control</button>
    <button class="b-r">bottom right control</button>
  </div>
<div id="map"></div>
</div>

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.