Cómo hacer que un <div> llene exactamente la ventana del navegador, incluido Mobile Safari a partir de 2019


10

Estoy trabajando en una aplicación web de una sola página, que generalmente se usará en dispositivos móviles. Una de sus características es un modo de mapa, que ocupa temporalmente toda la ventana del navegador; una escala de distancia y algunos controles están unidos a las cuatro esquinas del mapa. Aquí hay una pequeña captura de pantalla del mapa para que pueda decir de qué estoy hablando:

Captura de pantalla de la superposición de mapas

El mapa se implementa como un <div>con position: fixedy las cuatro coordenadas cero; Asimismo, establecer temporalmente el <body>que overflow: hiddenmientras que el mapa es visible para manejar el caso de la pantalla de la aplicación subyacente que se está desplazado lejos del origen. Eso es suficiente para que el mapa funcione exactamente como quiero en los navegadores de escritorio. Los navegadores móviles también requieren que le dé una etiqueta de meta viewport con algo así "width=device-width,user-scalable=no"para que el área visible de la ventana se corresponda exactamente con la ventana gráfica.

Todo esto funcionó maravillosamente hace unos años cuando originalmente escribí esta aplicación, pero en algún punto de la línea iOS Safari dejó de honrar cualquiera de las opciones de meta viewport que implican escalado, aparentemente muchos sitios estaban aplicando mal la etiqueta, lo que resultó en un texto que era indescifrablemente pequeño, pero inzoomable Actualmente, si habilita el mapa en este navegador, es probable que obtenga una vista ligeramente ampliada, que corta esos botones a la derecha e inferior, y no puede hacer nada al respecto, porque todos los toques se interpretan como gestos de zoom / panorámica para el mapa, en lugar de desplazarse por el navegador. El mapa no es terriblemente útil sin las funciones a las que se accede a través de esos botones, y sin el botón superior derecho, ni siquiera se puede cerrar el mapa. La única salida es volver a cargar la página, lo que puede provocar la pérdida de datos no guardados.

Definitivamente voy a agregar el uso de history.pushState/ onpopstatepara que la superposición del mapa se comporte como una página separada. Podrá salir del modo de mapa utilizando el botón Atrás del navegador, pero eso no soluciona el resto de la pérdida de la funcionalidad debido a la falta de botones.

He considerado usarlo .requestFullscreen()para implementar la superposición del mapa, pero no es compatible en todas partes donde la aplicación sería utilizable. En particular, aparentemente no funciona en absoluto en iPhones, y en iPads obtienes una barra de estado y un enorme botón 'X' que superpone tu contenido; mi escala de distancia probablemente ya no sea legible. De todos modos, no es semánticamente lo que realmente quiero: necesito la ventana completa , no la pantalla completa.

¿Cómo hago para que una pantalla completa funcione en navegadores modernos? Toda la información que puedo encontrar sobre el tema habla sobre el uso de la etiqueta meta viewport, pero como mencioné, ya no funciona.


1
@Joehat, la mayor parte de la aplicación es sensible; Ese no es el problema. Es solo esta función de superposición de mapas la que tiene un problema: los gestos táctiles se usan para hacer zoom / panoramizar el mapa (es un SVG, generado por d3.js), sin dejar forma de ajustar el zoom y el desplazamiento del navegador. Funcionó bien cuando el navegador me permitió controlar la ventana gráfica.
jasonharper

1
Algunas preguntas básicas: ¿Está utilizando un restablecimiento CSS? ¿Hay márgenes extraños o rellenos en algo? ¿Está el cuerpo configurado en 100vw x 100vh? ¿El cuerpo está posicionado en relación con su div de mapa para trabajar?
itsallgoodie

1
¿podría compartir un código de muestra para esto? Lo comprobaré y se lo haré saber
Ranjith v

1
muestra tu código !!
nikhil sugandh

1
Una captura de pantalla o algún ejemplo del contenido que se pone en esta ventana realmente ayudaría a determinar qué está pasando.
Bryce Howitson

Respuestas:



1

Debe establecer la altura del cuerpo y del html al 100%

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

1

¿Has probado estos?

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

(Supongo que te referías vwal ancho, no a vh...) ¿A qué elemento sugieres que agregue esto? Lo probé en varios lugares ( <html>, <body>y el mapa <div>), pero no vi diferencias.
jasonharper

Es para el div. ¿Hay alguna escala de transformación o propiedad de zoom aplicada a algún elemento?
Rajilesh Panoli

No hay transformaciones en el nivel HTML, el zoom / panorama de mi mapa se realiza aplicando traducciones a los elementos SVG que lo componen.
jasonharper

0

prueba esto:

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

Esto no cambió nada, y no veo ninguna razón para esperarlo: shrink-to-fit=yeses el valor predeterminado, y Safari ya no presta atención a las opciones de escala.
jasonharper




0

si usa position: fixedsolo el método CSS estándar que ha existido durante muchos años.

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

Esto solo hará que el tamaño automático div se ajuste al tamaño completo de la ventana gráfica, y al usar la posición fija, se bloquea en su lugar, no importa cuánto se desplace, puede deshabilitar el desplazamiento del cuerpo si lo necesita con

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

así que si solo agrega la clase noScroll a la etiqueta html, deshabilitará el desplazamiento. entonces, cuando desee permitir el desplazamiento nuevamente, puede hacerlo.


0

Puede implementar esto usando una estructura de dos capas para sus controles de mapa y su capa de mapa. Lo que significa que en realidad no necesita ninguno javascriptpara implementar lo que desea (aunque no se proporcionó ningún ejemplo de codificación en la pregunta). Puede manipular viewport CSSy ese es el significado real de vwy vhpara responder a su comentario ¿Cómo se supone que ayuda 100vw / 100vh? , puede ayudar ya que vsignifica viewport.

Ver el fragmento por ejemplo.

Se podría proporcionar un mejor ejemplo (ser más preciso en parámetros específicos que podrían perderse) si hubiera alguna codificación en la pregunta.

PD: la capa del mapa es simulada por una imagen que se amplía en el desplazamiento.

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>

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.