如何使 <div> 准确填充浏览器 window,包括截至 2019 年的 Mobile Safari

How to make a <div> exactly fill the browser window, including Mobile Safari as of 2019

我正在开发一个单页网络应用程序,该应用程序最常用于移动设备。它的特点之一是地图模式,可以暂时接管整个浏览器window;距离标尺和一些控件附加到地图的四个角。这是地图的小截图,所以你可以知道我在说什么:

地图实现为 <div>position: fixed,所有四个坐标均为零;我还临时将 <body> 设置为 overflow: hidden,而地图是可见的,以处理底层应用程序显示从原点滚动的情况。这足以使地图在桌面浏览器上完全按照我想要的方式工作。移动浏览器还要求我提供一个像 "width=device-width,user-scalable=no" 这样的元视口标签,以使 window 的可见区域与视口完全对应。

几年前,当我最初编写这个应用程序时,这一切都非常好,但在某个地方iOS Safari 停止尊重涉及的任何元视口选项缩放 - 显然有太多网站误用了标签,导致文本小得难以阅读,但也无法缩放。目前,如果您在此浏览器上启用地图,您可能会看到稍微放大的视图,这会切断右侧和底部的按钮 - 而您对此无能为力,因为所有触摸都被解释为地图的 zoom/pan 手势,而不是浏览器滚动。如果没有通过这些按钮访问的功能,地图就不会非常有用 - 如果没有右上角的按钮,您甚至无法关闭地图。唯一的出路是重新加载页面,这可能会导致未保存的数据丢失。

我肯定会添加 history.pushState/onpopstate 的使用,这样地图叠加层就像一个单独的页面。您可以使用浏览器的后退按钮退出地图模式 - 但这并不能解决由于缺少按钮而导致的其余功能损失。

我考虑过使用 .requestFullscreen() 来实现地图叠加层,但并非所有地方都支持该应用程序,否则该应用程序将可用。特别是,它显然在 iPhone 上根本不起作用,而在 iPad 上你会得到一个状态栏和一个巨大的 'X' 按钮覆盖你的内容 - 我的距离标尺可能不再可读。无论如何,这在语义上不是我真正想要的——我需要完整的 window,而不是全屏。

如何在现代浏览器上获得完整的window 显示?我能找到的关于该主题的所有信息都在谈论使用 meta viewport 标签,但正如我所提到的,它不再有效。

试试这个:

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

你试过这些吗?

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

因为我不能评论,我想补充一点,你应该检查你的 body 标签是否是浏览器的高度。您可能还想检查一下:Chrome / Safari not filling 100% height of flex parent

您需要将 body 和 html 的高度都设置为 100%

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

解决方案

使用 JavaScript 将全屏 div 的高度设置为 window.innerHeight,然后在 window 调整大小时更新它。

同样的问题:

更多信息:

这是一个旧的解决方案,解决了一个紧密相关但不完全相同的问题,所以我不确定它是否适用: https://github.com/gajus/brim

应该是类似于minimal-ui的解法。

这是引用此答案的另一个问题: iOS 8 removed "minimal-ui" viewport property, are there other "soft fullscreen" solutions?

如果这有帮助,请告诉我。

尝试使用以下代码 div

.class{height:100vh;}

如果您使用 position: fixed,只需使用已经存在多年的标准 CSS 方法。

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

这只会使 div 自动调整为视口的完整大小,并且使用固定位置无论它们滚动多少都会锁定到位,如果需要,您可以禁用主体滚动

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

因此,如果您只是将 noScroll class 添加到 html 标记,它将禁用滚动。然后当你想允许再次滚动时你可以。

您可以使用地图控件和地图图层的两层结构来实现这一点。这意味着您实际上不需要任何 javascript 来实现您想要的(尽管问题中没有给出编码示例)。您可以使用 CSS 操作视口,这就是 vwvh 的实际含义,以便回答您的​​评论 100vw/100vh 应该如何提供帮助?,它可以提供帮助,因为 v 代表视口。

例如,请参见代码段。

A better example (being more accurate on specific parameters that might be missed) could be provided if some coding was present in the question.

PS: 地图图层由滚动时放大的图像模拟。

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>