如何使 <div> 完全填满浏览器窗口,包括截至 2019 年的 Mobile Safari
Posted
技术标签:
【中文标题】如何使 <div> 完全填满浏览器窗口,包括截至 2019 年的 Mobile Safari【英文标题】:How to make a <div> exactly fill the browser window, including Mobile Safari as of 2019 【发布时间】:2020-03-27 08:41:37 【问题描述】:我正在开发一个单页网络应用程序,该应用程序最常用于移动设备。它的一个特点是地图模式,它暂时占据了整个浏览器窗口;距离标尺和一些控件附在地图的四个角上。这是地图的小屏幕截图,因此您可以说出我在说什么:
地图被实现为<div>
,position: fixed
和所有四个坐标为零;我还临时将<body>
设置为overflow: hidden
,而地图是可见的,以处理底层应用程序显示从原点滚动的情况。这足以使地图在桌面浏览器上完全按照我想要的方式工作。移动浏览器还要求我提供带有 "width=device-width,user-scalable=no"
之类的元视口标签,以使窗口的可见区域与视口完全对应。
这一切都非常好 几年前我最初编写这个应用程序时,但在某处 ios Safari 停止支持任何涉及缩放的元视口选项 - 显然太多的网站误用了标记,导致文本小得难以阅读,但无法缩放。目前,如果您在此浏览器上启用地图,您可能会得到一个稍微放大的视图,这会切断右侧和底部的那些按钮 - 而您对此无能为力,因为所有触摸都被解释为地图的缩放/平移手势,而不是浏览器滚动。如果没有通过这些按钮访问的功能,地图就不是非常有用 - 如果没有右上角的按钮,您甚至无法关闭地图。唯一的出路是重新加载页面,这可能会导致未保存的数据丢失。
我肯定会添加history.pushState
/onpopstate
的使用,这样地图叠加层就像一个单独的页面一样。您可以使用浏览器的后退按钮退出地图模式 - 但这并不能解决由于缺少按钮而导致的其余功能损失。
我考虑过使用 .requestFullscreen()
来实现地图叠加,但它并不支持在任何地方都可以使用该应用程序。特别是,它显然在 iPhone 上根本不起作用,在 iPad 上,你会看到一个状态栏和一个覆盖你内容的巨大“X”按钮——我的距离刻度可能不再可读。无论如何,这不是我真正想要的语义 - 我需要完整的窗口,而不是全屏。
如何在现代浏览器上获得全窗口显示?我能找到的关于该主题的所有信息都在谈论使用元视口标签,但正如我所提到的,它不再有效。
【问题讨论】:
@Joehat,大部分应用是响应式的;那不是问题。只是这个地图叠加功能存在问题:触摸手势用于缩放/平移地图(它是 SVG,由 d3.js 生成),无法调整浏览器的缩放和滚动。当浏览器允许我控制视口时,它工作得很好。 一些基本问题:您是否使用 CSS 重置?任何东西上是否有任何奇怪的边距或填充?车身是否设置为 100vw x 100vh?主体是否相对于您的地图 div 定位? 你能分享一下这个示例代码吗..我会检查并告诉你 显示你的代码!! 一张屏幕截图或一些被放入此窗口的内容示例将真正有助于确定发生了什么。 【参考方案1】:解决方案
使用 javascript 将全屏 div 的高度设置为 window.innerHeight
,然后在调整窗口大小时对其进行更新。
同样的问题:
https://***.com/a/37113430/8662476
更多信息:
https://css-tricks.com/the-trick-to-viewport-units-on-mobile/ https://nicolas-hoizey.com/2015/02/viewport-height-is-taller-than-the-visible-part-of-the-document-in-some-mobile-browsers.html【讨论】:
【参考方案2】:需要将body和html的高度都设置为100%
html, body
width: 100%;
height: 100%;
margin: 0;
【讨论】:
【参考方案3】:你试过这些吗?
width: 100vw;
height: 100vh;
margin: 0;
padding: 0;
【讨论】:
(我假设您的意思是宽度上的vw
,而不是vh
...)您建议我将其添加到哪个元素?我在几个地方尝试过(<html>
、<body>
和地图<div>
),但没有发现任何差异。
用于 div。是否有任何变换比例或缩放属性应用于任何元素。?
在 HTML 级别没有转换,我的地图缩放/平移是通过对组成它的 SVG 元素应用转换来完成的。【参考方案4】:
如果您使用position: fixed
,只需使用已存在多年的标准 CSS 方法即可。
.divFixedClass
position: fixed;
top:0;
left:0;
right:0;
bottom:0;
这只会使 div 自动调整为视口的完整大小,并使用固定位置,无论滚动多少,它都会锁定到位,如果需要,您可以禁用 body 滚动
html.noScroll, html.noScroll > body
overflow:none;
因此,如果您只是将 noScroll 类添加到 html 标记,它将禁用滚动。那么当你想再次允许滚动时,你可以。
【讨论】:
【参考方案5】:试试这个:
<meta name="viewport" content="width=device-width, height=device-height ,
initial-scale=1.0,user-scalable=no, shrink-to-fit=yes" />
【讨论】:
这并没有改变任何东西,我认为没有理由期待它:shrink-to-fit=yes
是默认设置,Safari 不再关注缩放选项。【参考方案6】:
由于我无法发表评论,我想补充一点,您应该检查您的 body 标签是否是浏览器的高度。您可能还想检查一下:Chrome / Safari not filling 100% height of flex parent
【讨论】:
【参考方案7】:这是一个旧的解决方案,解决了一个密切相关但不完全相同的问题,所以我不确定它是否适用: https://github.com/gajus/brim
应该是类似于minimal-ui的解决方案。
这是另一个引用此答案的问题: iOS 8 removed "minimal-ui" viewport property, are there other "soft fullscreen" solutions?
让我知道这是否有帮助。
【讨论】:
【参考方案8】:试试下面的 div 代码
.classheight:100vh;
【讨论】:
【参考方案9】:您可以为地图控件和地图图层使用两层结构来实现这一点。这意味着您实际上不需要任何 javascript
来实现您想要的(尽管问题中没有给出编码示例)。您可以使用CSS
操作视口,这就是vw
和vh
的实际含义,以便回答您的评论100vw/100vh 应该如何提供帮助?,它可以提供帮助,因为@ 987654325@ 代表视口。
以 sn-p 为例。
如果问题中存在某些编码,则可以提供更好的示例(对可能遗漏的特定参数更准确)。
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>
【讨论】:
以上是关于如何使 <div> 完全填满浏览器窗口,包括截至 2019 年的 Mobile Safari的主要内容,如果未能解决你的问题,请参考以下文章