一行代码修复100vh bug | 京东云技术团队

你知道奇怪的移动视口错误(也称为100vh bug)吗?或者如何以正确的方式创建全屏块?

一、100vh bug

什么是移动视口错误?

你是否曾经在网页上创建过全屏元素?只需添加一行 CSS 并不难:

1.my-page { 2 height: 100vh 3}

1vh是视口高度的1% ,正是我们所需要的。但当我们在移动设备上测试时,就会出现问题。移动浏览器的视口可以动态改变,但值保持不变。因此在移动浏览器中vh变成静态值并且不反映视口的实际高度。

在下图中,可以看到移动屏幕的两种状态:

带有隐藏的地址栏

具有可见的地址栏

核心问题是移动浏览器(Chrome 和 Safari)有一个“有用”的功能,地址栏有时可见,有时隐藏,从而改变视口的可见大小。这些浏览器并没有随着视口高度的变化而将高度调整100vh为屏幕的可见部分,而是将100vh地址栏设置为隐藏地址的浏览器高度。结果是,当地址栏可见时,屏幕的底部将被切断,从而违背了100vh最初的目的。

有什么方法可以解决这个问题?

二、常规修复

1. CSS + Javascript

使用的解决方案涉及使用CSS 自定义属性和一些Javascript。

简而言之,我们监听resize事件并在每次窗口大小更改时设置--vh自定义属性(窗口高度的1% ):

核心功能代码:

1//首先获得视口高度并将其乘以1%以获得1vh单位的值 2 let vh = window.innerHeight * 0.01 3 // 然后,我们将——vh自定义属性中的值设置为文档的根 4 document.documentElement.style.setProperty('--vh', `${vh}px`) 5 // 监听resize事件 视图大小发生变化就重新计算1vh的值 6 window.addEventListener('resize', () => { 7 // 执行与前面相同的脚本 8 let vh = window.innerHeight * 0.01 9 document.documentElement.style.setProperty('--vh', `${vh}px`) 10 })
1<div class="module"> 2 <div class="module__item">20%</div> 3 <div class="module__item">40%</div> 4 <div class="module__item">60%</div> 5 <div class="module__item">80%</div> 6 <div class="module__item">100%</div> 7</div>
1body { 2 background-color: #333; 3} 4 5.module { 6 height: 100vh; /* 不支持自定义属性时的回退操作*/ 7 height: calc(var(--vh, 1vh) * 100); 8 margin: 0 auto; 9 max-width: 30%; 10} 11 12.module__item { 13 align-items: center; 14 display: flex; 15 height: 20%; 16 justify-content: center; 17} 18 19.module__item:nth-child(odd) { 20 background-color: #fff; 21 color: #F73859; 22} 23 24.module__item:nth-child(even) { 25 background-color: #F73859; 26 color: #F1D08A; 27}

2. 使用 -webkit-fill-available

1 2.my-page { 3 background-color: #ffffff; 4 min-height: 100vh; 5 min-height: -webkit-fill-available; 6 overflow-y: scroll; 7 padding-bottom: 50px; 8 }

此方法chrome浏览器中在某些情况下使用会有问题。

因此引出下文第三种方法。

3. postcss-100vh-fix

当然,你也可以使用第三方库来进行修复,具体使用可查看其官网 postcss-100vh-fix。

它适用于 Chrome( -webkit-fill-available 在某些情况下只会在 Chrome 中导致问题)、iOS/iPad/MacOS Safari 和 所有其他浏览器 。纯CSS解决方案,无需JS。

1body { 2 /* Footer will be hidden on iOS Safari because of bottom panel */ 3 height: 100vh; 4}
1body { 2 height: 100vh; 3} 4 5/* Avoid Chrome to see Safari hack */ 6@supports (-webkit-touch-callout: none) { 7 body { 8 /* The hack for Safari */ 9 height: -webkit-fill-available; 10 } 11}

此方法不适用于部分高度,例如height: 90vh 或height: calc(100vh - 60px)

三、更好的方法

根据CSS Values 4 规范:视口相对长度,我们可以使用新的视口单位。

有一个dvh单位可以完成全部工作。它始终会适应视口大小。最后,浏览器支持如下:

有了这个很酷的功能,解决方案变得非常简单,只需要一行 CSS:

1.my-page { 2 height: 100dvh 3}

可以在此了解更多的动态视口单元信息,如:dvw、dvh、dvi、dvb、dvmin 和 dvmax等。

结论

如今,CSS 发展迅速,对解决前端问题有很大帮助。该dvh单位是制作视口相关高度的最佳选择。这是一个非常简单而强大的 CSS 功能,可以让你的工作变得更加轻松。

作者:京东保险 张洁

来源:京东云开发者社区 转载请注明来源

点赞
收藏

评论区

加载中...

相关推荐

Oracle 分组与拼接字符串同时使用

SELECTT.,ROWNUMIDFROM(SELECTT.EMPLID,T.NAME,T.BU,T.REALDEPART,T.FORMATDATE,SUM(T.S0)S0,MAX(UPDATETIME)CREATETIME,LISTAGG(TOCHAR(

MySQL部分从库上面因为大量的临时表tmp_table造成慢查询

背景描述Time:20190124T00:08:14.70572408:00User@Host:@Id:Schema:sentrymetaLast_errno:0Killed:0Query_time:0.315758Lock_

皕杰报表之UUID

​在我们用皕杰报表工具设计填报报表时,如何在新增行里自动增加id呢?能新增整数排序id吗?目前可以在新增行里自动增加id,但只能用uuid函数增加UUID编码,不能新增整数排序id。uuid函数说明:获取一个UUID,可以在填报表中用来创建数据ID语法:uuid()或uuid(sep)参数说明:sep布尔值,生成的uuid中是否包含分隔符'',缺省为

mysql中like用法

like的通配符有两种%(百分号):代表零个、一个或者多个字符。\(下划线):代表一个数字或者字符。1\.name以"李"开头wherenamelike'李%'2\.name中包含"云",“云”可以在任何位置wherenamelike'%云%'3\.第二个和第三个字符是0的值wheresalarylike'\00%'4\

VBox 启动虚拟机失败

在Vbox(5.0.8版本)启动Ubuntu的虚拟机时,遇到错误信息:NtCreateFile(\\Device\\VBoxDrvStub)failed:0xc000000034STATUS\_OBJECT\_NAME\_NOT\_FOUND(0retries) (rc101)Makesurethekern

FLV文件格式

1.        FLV文件对齐方式FLV文件以大端对齐方式存放多字节整型。如存放数字无符号16位的数字300(0x012C),那么在FLV文件中存放的顺序是:|0x01|0x2C|。如果是无符号32位数字300(0x0000012C),那么在FLV文件中的存放顺序是:|0x00|0x00|0x00|0x01|0x2C。2.