深入理解 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>
相关推荐
两个西柚呀2 小时前
未在props中声明的属性
前端·javascript·vue.js
子伟-H55 小时前
App开发框架调研对比
前端
桃子不吃李子5 小时前
axios的二次封装
前端·学习·axios
SteveJrong5 小时前
面试题 - JavaScript
前端·javascript·面试·ecmascript·基础·找工作·红宝书
阿金要当大魔王~~5 小时前
uniapp 页面标签 传值 ————— uniapp 定义 接口
前端·javascript·uni-app·1024程序员节
全栈软件开发5 小时前
uniapp三端影视源码苹果cms自动采集电影视频网站源码前端源码带VIP
前端·uni-app·影视源码
chxii6 小时前
10.4FormData :前端文件上传与表单数据处理的核心工具
前端
AntBlack6 小时前
不当韭菜 : 好像真有点效果 ,想藏起来自己用了
前端·后端·python
楊无好6 小时前
react中props的使用
前端·react.js·前端框架
一个处女座的程序猿O(∩_∩)O6 小时前
Vue-Loader 深度解析:原理、使用与最佳实践
前端·javascript·vue.js