深入理解 svh、lvh、dvh—— 移动端视口高度解决方案

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;
}
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>
相关推荐
大怪v21 小时前
【Virtual World 04】我们的目标,无限宇宙!!
前端·javascript·代码规范
狂炫冰美式21 小时前
不谈技术,搞点文化 🧀 —— 从复活一句明代残诗破局产品迭代
前端·人工智能·后端
xw51 天前
npm几个实用命令
前端·npm
!win !1 天前
npm几个实用命令
前端·npm
代码狂想家1 天前
使用openEuler从零构建用户管理系统Web应用平台
前端
dorisrv1 天前
优雅的React表单状态管理
前端
蓝瑟1 天前
告别重复造轮子!业务组件多场景复用实战指南
前端·javascript·设计模式
dorisrv1 天前
高性能的懒加载与无限滚动实现
前端
韭菜炒大葱1 天前
别等了!用 Vue 3 让 AI 边想边说,字字蹦到你脸上
前端·vue.js·aigc
StarkCoder1 天前
求求你,别在 Swift 协程开头写 guard let self = self 了!
前端