太长不看 (TL;DR)
- CSS 迎来数个新相对 viewport 的尺寸单位——其中
lvw、svw、dvw分别代表“大视窗宽度百分比”、“小视窗宽度百分比”、“动态视窗宽度百分比”;viewport 高度百分比尺寸同理。- “大视窗”、“小视窗”分别代表浏览器“工具栏收起”、“工具栏展开”场景下的视窗;“动态视窗”则代表跟随浏览器工具栏尺寸变化的实时视窗大小。
正文
温馨提示:对
vw、vh或viewport概念不熟悉的同学请先自行补课。
相信很多小伙伴遇到过写“全屏页面”的需求。桌面端好说——直接 width: 100vw、height: 100vh 就行。但到了移动端,事情就没这么简单了——移动端浏览器的 视窗 大小会动态变化。
以 Safari (iOS 16.0.2) 为例,新开页面时页面底部工具栏很明显,此时工具栏最大化展开,视窗为小视窗;当滚动距离超过阈值后,工具栏会进入最小化状态,此时视窗为大视窗:
这里不方便传视频,对此特性不熟悉的同学建议拿出手机自行感受一下。
W3C 在 CSS Values and Units Module Level 3 及之前的标准中 vw、vh 等相对视窗尺寸为“响应变化的初始包含块的尺寸”,并没有规定最大、最小的视窗尺寸。而在 Level 4 中,W3C 对此做了定义:
lv*开头的尺寸单位是相对于“大视窗”(工具栏收起)的 1%,浏览器尺寸不变时是个固定值sv*开头的尺寸单位是相对于“小视窗”(工具栏展开)的 1%,浏览器尺寸不变时是个固定值dv*开头的尺寸单位是相对于“当前视窗”大小的 1%v*开头的尺寸单位相对于的视窗尺寸要介于“大视窗”和“小视窗”之间,单位长度为视窗尺寸的 1%(此标准尚有争议)
上述前缀适用于 vw, vh, vmin, vmax 等各种视窗相对百分比单位。
在 Safari (iOS 16.0.2) 测试一下可以发现:小视窗时 100svh 刚好填充屏幕,大视窗时 100lvh 刚好填充屏幕,而 100dvh 则与当前视窗尺寸保持一致。(代码见附录)
不过看起来还有问题:工具栏的背景颜色应该是模糊红色(蒙层覆盖在 100lvh 之上),但上图小视窗截图里看来并没有模糊。这个问题我记得之前也遇到过,后续有时间再学习一下。
兼容性
根据 Can I Use 的数据(源自 MDN browser-compat-data),截止到2022年11月21日,全球仅有约 18% 的浏览器支持了相关属性。
BTW
现在,相对视窗百分比尺寸单位有了前缀 lv*, sv* 等,有了后缀 *vw, *vh 等,所以所有相关尺寸都可以简写为 *v* —— 一张可爱的笑脸诞生啦~
所以我宣布,这么好用的单位,以后一律叫可爱单位!*v*
附录:新单位测试代码
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Demo - CSS Values and Units Module Level 4</title>
</head>
<style>
body { margin: 0; height: 200vh }
.vh {
width: 100vw;
position: fixed;
top: 0;
left: 0;
display: flex;
align-items: flex-end;
color: #fff;
}
#lvh { height: 100lvh; z-index: 1; background-color: #700 }
#svh { height: 100svh; z-index: 2; background-color: #070 }
#dvh { height: 100dvh; z-index: 3; justify-content: flex-end }
</style>
<body>
<div class="vh" id="lvh">100lvh</div>
<div class="vh" id="svh">100svh</div>
<div class="vh" id="dvh">100dvh</div>
</body>
</html>