深入理解 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>
相关推荐
子兮曰3 天前
jev-ultrafast 深度解析:7 秒订机票的浏览器 Agent 是如何炼成的
前端·后端·agent
子兮曰3 天前
Jev 爆发一周:7 秒 Agent 背后的 System One 生态与三场争议
前端·后端·ai编程
前端小万3 天前
写公众号赚了 3000 块后,我做了一款叫 "一键成稿" 的软件
前端·微信小程序
爱勇宝3 天前
ZCode 开源 24 小时:一份没有历史的账本,回答不了"有没有偷代码"
前端·后端·chatglm (智谱)
三十而立洋3 天前
Cookie 详解:从产生到安全,一次讲透
前端·javascript
卡布鲁3 天前
把一个 Vite + Vue3 应用塞进 qiankun (React + Umi3) 主站:十个坑的复盘
前端·javascript·react.js
汉堡大王95273 天前
Jev:不是聊天机器人, 而是一个智能 if 语句
前端·人工智能·后端
梦想很大很大3 天前
从运行事实到回归证据:Workrun 的 Telemetry 与 Evaluation 实践
前端·人工智能·后端
计算机魔术师3 天前
Meta Muse agent 接入 Shopify 的 Shop Pay 实现代理式购物
前端
沙蒿同学3 天前
我用 Go 搭了一条 AI Agent 流水线:从 1 张商品图到一整套淘宝详情页
前端·javascript·后端