Como fazer um <div> preencher exatamente a janela do navegador, incluindo o Mobile Safari a partir de 2019


10

Estou trabalhando em um aplicativo Web de página única, que normalmente será usado em dispositivos móveis. Um de seus recursos é o modo de mapa, que assume temporariamente a janela inteira do navegador; uma escala de distância e alguns controles são anexados aos quatro cantos do mapa. Aqui está uma pequena captura de tela do mapa para que você possa dizer do que estou falando:

Captura de tela da sobreposição de mapa

O mapa é implementado como um <div>com position: fixede todas as quatro coordenadas zero; Eu também definir temporariamente a <body>para overflow: hiddenenquanto o mapa é visível para lidar com o caso do visor aplicativo subjacente sendo rolada para longe da origem. Isso é suficiente para fazer o mapa funcionar exatamente como eu quero nos navegadores de desktop. Os navegadores móveis também exigem que eu forneça uma tag de meta viewport com algo parecido "width=device-width,user-scalable=no"para fazer com que a área visível da janela corresponda exatamente à viewport.

Tudo funcionou lindamente alguns anos atrás quando eu escrevi esse aplicativo, mas em algum momento o iOS Safari parou de honrar qualquer uma das opções de meta viewport que envolviam o dimensionamento - aparentemente muitos sites estavam aplicando mal a tag, resultando em um texto incrivelmente pequeno, ainda que não seja sustentável. Atualmente, se você ativar o mapa neste navegador, é provável que você tenha uma visualização levemente ampliada, que corta esses botões à direita e na parte inferior - e você não pode fazer nada a respeito, porque todos os toques são interpretados como gestos de zoom / panorâmica para o mapa, em vez de rolagem do navegador. O mapa não é muito útil sem os recursos acessados ​​por esses botões - e sem o botão superior direito, você não pode nem fechar o mapa. A única saída é recarregar a página, o que pode resultar na perda de dados não salvos.

Definitivamente vou adicionar o uso de history.pushState/ onpopstatepara que a sobreposição do mapa se comporte como uma página separada. Você seria capaz de sair do modo de mapa usando o botão Voltar do navegador - mas isso não soluciona o restante da perda da funcionalidade devido à falta de botões.

Eu considerei usar .requestFullscreen()para implementar a sobreposição de mapa, mas não há suporte em todos os lugares que o aplicativo possa ser usado. Aparentemente, ele aparentemente não funciona em iPhones, e nos iPads você recebe uma barra de status e um enorme botão 'X' sobrepondo seu conteúdo - minha escala de distância provavelmente não seria mais legível. De qualquer maneira, não é semanticamente o que realmente quero - preciso da janela inteira , não da tela cheia.

Como obtenho uma exibição em janela cheia trabalhando em navegadores modernos? Todas as informações que posso encontrar sobre o assunto falam sobre o uso da tag meta viewport, mas como mencionei, isso não funciona mais.


11
@ Joeo, a maior parte do aplicativo é responsiva; esse não é o problema. É apenas esse recurso de sobreposição de mapa que tem um problema: os gestos de toque são usados ​​para ampliar / mover o mapa (é um SVG, gerado pelo d3.js.), não deixando como ajustar o zoom e a rolagem do navegador. Funcionou bem quando o navegador me permitiu controlar a janela de exibição.
precisa saber é o seguinte

11
Algumas perguntas básicas: Você está usando uma redefinição de CSS? Existe alguma margem ou preenchimento estranho em alguma coisa? O corpo está definido para 100vw x 100vh? O corpo está posicionado em relação à sua div do mapa para trabalhar?
itsallgoodie

11
você pode compartilhar o código de exemplo para isso .. vou verificar e informá-lo #
Ranjith v

11
mostre seu código !!
Nikhil sugandh 05/12/19

11
Uma captura de tela ou algum exemplo do conteúdo que está sendo colocado nessa janela realmente ajudaria a determinar o que está acontecendo.
Bryce Howitson

Respostas:



1

Você precisa definir a altura do corpo e do html para 100%

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

1

Você já tentou isso?

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

(Presumo que você quis dizer vwa largura, não vh...) A que elemento você está sugerindo que eu adicione isso? Eu tentei-o em vários lugares ( <html>, <body>e o mapa <div>), mas não viu nenhuma diferença.
jasonharper

É para o div. Existe alguma propriedade de escala ou zoom de transformação aplicada a qualquer elemento.?
Rajilesh Panoli

Não há transformações no nível HTML, meu zoom / panorâmica é feito aplicando traduções aos elementos SVG que o compõem.
jasonharper

0

tente isto:

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

Isso não mudou nada, e não vejo motivo para esperar: shrink-to-fit=yesé o padrão, e o Safari não presta mais atenção às opções de dimensionamento.
precisa saber é o seguinte




0

se você estiver usando, position: fixeduse o método CSS padrão que existe há muitos anos.

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

Isso apenas fará com que o div seja dimensionado automaticamente para o tamanho total da janela de visualização e, usando a posse fixa, ela esteja bloqueada no lugar, não importa o quanto eles rolem, você pode desativar a rolagem do corpo se precisar

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

portanto, se você adicionar a classe noScroll à tag html, ela desabilitará a rolagem. quando você quiser permitir a rolagem novamente, poderá.


0

Você pode implementar isso usando uma estrutura de duas camadas para seus controles de mapa e sua camada de mapa. Significando que você realmente não precisa de nenhum javascriptpara implementar o que deseja (embora nenhum exemplo de codificação tenha sido dado na pergunta). Você pode manipular a viewport com CSSe esse é o significado real de vwe vhpara responder seu comentário Como é que 100vw / 100vh deve ajudar? , pode ajudar, pois vsignifica viewport.

Veja o trecho, por exemplo.

Um exemplo melhor (sendo mais preciso em parâmetros específicos que podem ser perdidos) poderia ser fornecido se alguma codificação estivesse presente na pergunta.

PS: a camada do mapa é simulada por uma imagem que é ampliada na rolagem.

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>

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.