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

一、100vh bug

什么是移动视口错误?

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

.my-page {
height: 100vh
}

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

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

带有隐藏的地址栏

具有可见的地址栏

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

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

二、常规修复

1. CSS + Javascript

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

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

核心功能代码:

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

2. 使用 -webkit-fill-available


.my-page {
background-color: #ffffff;
min-height: 100vh;
min-height: -webkit-fill-available;
overflow-y: scroll;
padding-bottom: 50px;
}

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

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

3. postcss-100vh-fix

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

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

body {
/* Footer will be hidden on iOS Safari because of bottom panel */
height: 100vh;
}
body {
height: 100vh;
} /* Avoid Chrome to see Safari hack */
@supports (-webkit-touch-callout: none) {
body {
/* The hack for Safari */
height: -webkit-fill-available;
}
}

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

三、更好的方法

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

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

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

.my-page {
height: 100dvh
}

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

结论

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

作者:京东保险 张洁

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

一行代码修复100vh bug | 京东云技术团队的更多相关文章

  1. springboot升级过程中踩坑定位分析记录 | 京东云技术团队

    作者:京东零售 李文龙 1.背景 " 俗话说:为了修复一个小bug而引入了一个更大bug " 因所负责的系统使用的spring框架版本5.1.5.RELEASE在线上出过一个偶发的 ...

  2. 融云技术分享:融云安卓端IM产品的网络链路保活技术实践

    本文来自融云技术团队原创分享,原文发布于“ 融云全球互联网通信云”公众号,原题<IM 即时通讯之链路保活>,即时通讯网收录时有部分改动. 1.引言 众所周知,IM 即时通讯是一项对即时性要 ...

  3. 从单个系统到云翼一体化支撑,京东云DevOps推进中的一波三折

    作者:王利莹 采访嘉宾:京东云DevOps团队负责人 郑永宽 今年,IDC 特别针对中国地区发布了<IDC MarketScape:中国 DevOps 云市场2019,厂商评估>研究报告, ...

  4. 京东云携手Mellanox,设计最先进SDN硬件加速功能并开源

    京东云携手Mellanox,设计最先进SDN硬件加速功能并开源 最新技术播报 京东云开发者社区  导语新一代 SDN.NFV 和云原生计算技术正在推动应用实例的极限,这些实例可以在虚拟化和容器化的服务 ...

  5. 融云技术分享:解密融云IM产品的聊天消息ID生成策略

    本文来自融云技术团队原创分享,原文发布于“融云全球互联网通信云”公众号,原题<如何实现分布式场景下唯一 ID 生成?>,即时通讯网收录时有部分改动. 1.引言 对于IM应用来说,消息ID( ...

  6. 京东云开发者|京东云RDS数据迁移常见场景攻略

    云时代已经来临,云上很多场景下都需要数据的迁移.备份和流转,各大云厂商也大都提供了自己的迁移工具.本文主要介绍京东云数据库为解决用户数据迁移的常见场景所提供的解决方案. 场景一:数据迁移上云 数据迁移 ...

  7. 【原创】够强!一行代码就修复了我提的Dubbo的Bug。

    这是 why 技术的第 28 篇原创文章 之前在<Dubbo 一致性哈希负载均衡的源码和 Bug,了解一下?>中写到了我发现了一个 Dubbo 一致性哈希负载均衡算法的 Bug. 对于解决 ...

  8. 华为云实战开发】5.如何快速创建免费Git代码仓库【华为云技术分享】

    1 文章目的 本文主要帮助已经掌握或者想要掌握Git的开发者,如何更好的应用Git,以及更好的将Git与DevCloud结合应用. 2 概述 2.1 版本控制系统介绍 从狭义上来说,版本控制系统是软件 ...

  9. 技术沙龙|京东云DevOps自动化运维技术实践

    自动化测试体系不完善.缺少自助式的持续交付平台.系统间耦合度高服务拆分难度大.成熟的DevOps工程师稀缺,缺少敏捷文化--这些都是DevOps 在落地过程中,或多或少会碰到的问题,DevOps发展任 ...

  10. JOIN US | 京东云诚聘技术精英

    清新的办公区域感受自然的气息,温馨的团队为你我放飞青春的理想 上有天文下有地理的阅读区域 各类图书提供借阅 绿植环绕生机勃勃的会客区域洋溢青春 [高级Java工程师] 职位描述: 参与云计算相关平台/ ...

随机推荐

  1. 如何做一个完美的api接口?

    如何做一个api接口?:我们知道API其实就是应用程序编程接口,可以把它理解为是一种通道,用来和不同软件系统间进行通信,本质上它是预先定义的函数:-api,接口 1 我们知道API其实就是应用程序编程 ...

  2. selenium-wire兼容selenium和requests

    背景 在工作中UI自动化中可能会需要用到API来做一些数据准备或清理的事情,那UI操作是略低效的,但API操作相对高效. 而实战课就有这样一个案例,不过那个案例是UI操作和API分开的. 极少会遇到这 ...

  3. 让你的HpSocket Pull支持同步(应答式)操作

    什么是HPSocket HP-Socket 是一套通用的高性能 TCP/UDP 通信框架,包含服务端组件.客户端组件和Agent组件,广泛适用于各种不同应用场景的 TCP/UDP 通信系统,提供 C/ ...

  4. Mac SpringBoot项目 Gradle 7.3 转 Maven 手把手教学,包学会~

    导读 最近我手上有个使用Gradle构建的项目,国内使用Gradle的人相对较少.而且我也觉得Gradle的依赖管理方式有些复杂,让我感到有些困惑.因此,我想将项目转换为Maven构建方式.Maven ...

  5. java正则表达式过滤工具类

    正则表达式过滤工具类 import java.util.regex.Matcher; import java.util.regex.Pattern; /** * @Description : * @D ...

  6. 创建第一个C语言文件

    创建第一个C语言文件 新建=>项目=>空项目 创建.c文件 我们学的是C语言,c++就不写了 调整字体 快捷键:Ctlr + 鼠标滚轮 通过工具调整 工具库与main()函数 打开一个工具 ...

  7. 「co-examination - A」

    破壁,组合意义法: 五种颜色 \(\star,a,b,c,d\). 对于 l.h.s. 钦定 \(k\),在 \(3n+k\) 个球中选出 \(2n\) 个球染色,在靠左的 \(n\) 个球中选 \( ...

  8. Solution -「洛谷 P3600」随机数生成器

    Desciption Link. 给定一个值域在 \([1,x]\) 的长度为 \(n\) 的序列(由随机数构成),求给定一组区间中的最小值的最大值的期望. Solution 记: \[w=\max\ ...

  9. MySQL数据库操作 Lab1

              实验一 MySQL数据库操作 实验目的: 掌握MySQL安装.配置与登录方法,使用MySQL客户创建数据库及对数据库表完成各种操作 实验内容: 1. 安装MySQL数据库管理系统, ...

  10. 【Azure Key Vault】在Azure Databricks上获取Azure Key Vault中所存储的机密(secret)的两种方式

    问题描述 在Azure Databricks上获取Azure Key Vault中所存储的机密(secret)的两种方式? 问题解答 方式一: 在Databricks的Notebook 中,直接编写P ...