svh、lvh、dvh是什么?
它们是 CSS 中以 视口高度(Viewport Height)为基础 的 相对单位,分别代表:
单位 | 全称 | 中文含义 | 说明 |
---|---|---|---|
svh | small viewport height | 小视口高度 | 表示浏览器 UI(如地址栏)显示时的最小视口高度 |
lvh | large viewport height | 大视口高度 | 表示浏览器 UI(如地址栏)隐藏时的最大视口高度 |
dvh | dynamic viewport height | 动态视口高度 | 表示根据浏览器UI显隐状态动态调整的视口高度,是当前真正可用的屏幕高度 |
为什么需要它们?------ vh的移动端痛点
css
height: 100vh; /* 视口高度的 100% */
vh(Viewport Height)单位,代表的是浏览器窗口的初始视口高度。在桌面端浏览器中,它通常没有问题。
但在 移动端浏览器(如 iOS Safari、Android Chrome) 中,情况就变得复杂了 👇:
移动端浏览器的特殊行为:
-
当页面加载时,浏览器通常会显示 顶部的导航栏/地址栏,此时 可视区域较小;
-
当用户向下滚动页面时,地址栏通常会 自动隐藏,此时 可视区域变大;
-
反之,当用户向上回滚时,地址栏可能又 重新显示,可视区域再次变小;
这就导致了 100vh并不等于用户"真正看到的屏幕高度",而是浏览器最初加载时的一个固定视口高度。因此会造成以下问题:
-
页面内容被地址栏遮挡,出现布局错位或顶部白边;
-
滚动时页面高度"跳动",体验差;
-
全屏弹窗、沉浸式页面无法真正铺满用户可见屏幕;
解决方案:使用动态视口单位 svh、lvh、dvh
CSS Working Group 引入了动态视口单位:svh、lvh、dvh,它们能够根据浏览器 UI(如导航栏、工具栏)的显隐状态,动态调整视口高度的基准值,从而让布局更加精准、体验更加流畅。
dvh(Dynamic Viewport Height)------ 动态视口高度
100dvh表示:当前用户真正可以看到的屏幕高度,会随着地址栏的显隐自动调整!
✅ 特点:
-
动态响应:当地址栏隐藏时,视口高度变大;地址栏显示时,视口高度变小;
-
真正可用:代表的是用户当前可以实际看到的页面区域,不是初始加载时的固定高度;
-
最佳实践:适用于几乎所有需要"铺满屏幕"或"基于屏幕高度布局"的移动端场景;
✅ 推荐使用场景:
-
移动端 H5 页面整体布局
-
全屏弹窗 / Modal / Drawer
-
沉浸式页面(如游戏、视频、活动页)
-
避免地址栏显隐影响布局的任何组件
✅ 示例代码:
css
.container {
height: 100dvh; /* 高度始终等于当前用户可见的屏幕高度 */
background: lightblue;
}
html
<template>
<div class="full-screen">
<!-- 你的内容 -->
</div>
</template>
<style scoped>
.full-screen {
height: 100dvh;
display: flex;
align-items: center;
justify-content: center;
}
</style>
svh(Small Viewport Height)------ 小视口高度
表示 浏览器 UI(如地址栏、工具栏)显示时 的最小视口高度。
✅ 特点:
-
是保守的、最小的可用视口高度;
-
适用于你希望内容始终不超出最小可视区域的场景;
-
一般用于边界保护、防止内容被裁剪等场景;
lvh(Large Viewport Height)------ 大视口高度
表示 浏览器 UI(如地址栏、工具栏)隐藏时 的最大视口高度。
✅ 特点:
-
是最大的可能可视区域高度;
-
适用于你希望充分利用"地址栏隐藏后更大屏幕空间"的场景;
-
比 dvh更大,但不如 dvh灵活(因为不会动态变化)
实际代码示例
移动端全屏布局
css
html, body {
height: 100dvh;
margin: 0;
overflow: hidden;
}
全屏弹窗 / Modal
css
.modal-overlay {
position: fixed;
top: 0;
left: 0;
width: 100dvw;
height: 100dvh;
background: rgba(0, 0, 0, 0.7);
display: flex;
align-items: center;
justify-content: center;
}
在 Vue中使用
html
<template>
<div class="hero-section">
<h1>欢迎来到全屏页面</h1>
</div>
</template>
<style scoped>
.hero-section {
height: 100dvh;
display: flex;
align-items: center;
justify-content: center;
background: linear-gradient(to bottom, #64b3f4, #c2e59c);
color: white;
text-align: center;
}
</style>