Come creare un <div> riempire esattamente la finestra del browser, incluso Mobile Safari a partire dal 2019


10

Sto lavorando su un'app Web a pagina singola, che in genere verrà utilizzata su dispositivi mobili. Una delle sue caratteristiche è una modalità mappa, che occupa temporaneamente l'intera finestra del browser; una scala della distanza e alcuni controlli sono collegati ai quattro angoli della mappa. Ecco un piccolo screenshot della mappa in modo da poter dire di cosa sto parlando:

Schermata della sovrapposizione della mappa

La mappa è implementata come <div>con position: fixedzero e tutte e quattro le coordinate zero; Ho anche impostato temporaneamente <body>a overflow: hiddenmentre la mappa è visibile per gestire il caso della visualizzazione dell'app sottostante che scorre via dall'origine. È sufficiente per far funzionare la mappa esattamente come voglio sui browser desktop. I browser mobili hanno anche richiesto che io fornissi un tag meta viewport con qualcosa del genere "width=device-width,user-scalable=no"per rendere esattamente l'area visibile della finestra esattamente corrispondente al viewport.

Tutto questo ha funzionato magnificamente qualche anno fa quando ho scritto questa app, ma da qualche parte lungo la linea iOS Safari ha smesso di onorare una qualsiasi delle opzioni di meta viewport che coinvolgono il ridimensionamento: a quanto pare troppi siti stavano applicando erroneamente il tag, risultando in un testo illeggibilmente piccolo, ma nonzoomabile. Al momento, se abiliti la mappa su questo browser, è probabile che tu abbia una vista leggermente ingrandita, che interrompe quei pulsanti a destra e in basso e non puoi farci nulla, poiché tutti i tocchi vengono interpretati come gesti di zoom / panoramica per la mappa, anziché come scorrimento del browser. La mappa non è terribilmente utile senza le funzionalità accessibili tramite quei pulsanti e senza il pulsante in alto a destra, non puoi nemmeno chiudere la mappa. L'unica via d'uscita è ricaricare la pagina, il che può comportare la perdita di dati non salvati.

Aggiungerò sicuramente l'uso di history.pushState/ in onpopstatemodo che l'overlay della mappa si comporti come una pagina separata. Saresti in grado di uscire dalla modalità mappa utilizzando il pulsante Indietro del browser, ma ciò non risolve il resto della perdita della funzionalità a causa della mancanza di pulsanti.

Ho pensato di utilizzare .requestFullscreen()per implementare l'overlay della mappa, ma non è supportato ovunque che l'app sarebbe altrimenti utilizzabile. In particolare, a quanto pare non funziona affatto su iPhone e su iPad ottieni una barra di stato e un enorme pulsante 'X' che sovrappone i tuoi contenuti - la mia scala di distanza probabilmente non sarebbe più leggibile. Non è semanticamente quello che voglio davvero, comunque - ho bisogno della finestra intera , non dello schermo intero.

Come faccio a far funzionare una visualizzazione a finestra intera sui browser moderni? Tutte le informazioni che posso trovare sull'argomento parlano dell'uso del tag meta viewport, ma come ho già detto, non funziona più.


1
@Joehat, la maggior parte dell'app è reattiva; non è questo il problema. È proprio questa funzionalità di overlay della mappa che ha un problema: i gesti tattili vengono utilizzati per ingrandire / spostare la mappa (è un SVG, generato da d3.js), senza lasciare alcun modo per regolare lo zoom e lo scorrimento del browser. Ha funzionato benissimo quando il browser mi ha permesso di controllare il viewport.
Jasonharper il

1
Alcune domande di base: stai utilizzando un ripristino CSS? Ci sono strani margini o imbottiture su qualcosa? Il corpo è impostato su 100vw x 100vh? Il corpo è posizionato in modo che la tua mappa div possa funzionare?
itsallgoodie,

1
puoi per favore condividere il codice di esempio per questo .. controllerò e ti farò sapere
Ranjith v

1
mostra il tuo codice !!
nikhil sugandh,

1
Uno screenshot o qualche esempio del contenuto che viene inserito in questa finestra potrebbe davvero aiutare a determinare cosa sta succedendo.
Bryce Howitson,

Risposte:



1

Devi impostare l'altezza sia del corpo che dell'html al 100%

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

1

Hai provato questi?

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

(Suppongo che intendessi vwsulla larghezza, non vh...) A quale elemento stai suggerendo di aggiungere questo? Ho provato in diversi luoghi ( <html>, <body>, e la mappa <div>), ma ho visto nessuna differenza.
Jasonharper,

È per il div. C'è qualche scala di trasformazione o proprietà dello zoom applicata a qualche elemento.?
Rajilesh Panoli,

Non ci sono trasformazioni a livello HTML, lo zoom / panoramica della mia mappa viene eseguito applicando traduzioni agli elementi SVG che lo compongono.
Jasonharper,

0

prova questo:

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

Questo non ha cambiato nulla e non vedo alcun motivo di aspettarselo: shrink-to-fit=yesè l'impostazione predefinita e Safari non presta più attenzione alle opzioni di ridimensionamento.
Jasonharper,




0

se stai usando position: fixedsemplicemente usa il metodo CSS standard che esiste da molti anni.

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

Questo ridurrà automaticamente la dimensione automatica del div alla dimensione intera del viewport e, usando possition riparato, sarà bloccato in posizione indipendentemente da quanto scorrano, potresti disabilitare lo scroll corporeo se necessario con

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

quindi se aggiungi semplicemente la classe noScroll al tag html disabiliterà lo scorrimento. quindi quando si desidera consentire nuovamente lo scorrimento, è possibile.


0

È possibile implementarlo utilizzando una struttura a due livelli per i controlli della mappa e il livello della mappa. Significa che in realtà non hai bisogno di nessuno javascriptper implementare ciò che desideri (anche se nella domanda non è stato fornito alcun esempio di codifica). Puoi manipolare il viewport con CSSe questo è il vero significato vwe vhper rispondere al tuo commento. Come dovrebbe essere d'aiuto 100vw / 100vh? , può essere utile dal momento che vsta per viewport.

Vedi lo snippet per esempio.

Un esempio migliore (essendo più accurato su parametri specifici che potrebbero non essere rilevati) potrebbe essere fornito se nella domanda fosse presente un codice.

PS: il livello della mappa è simulato da un'immagine che viene ingrandita sullo scorrimento.

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>

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.