CSS 视口单位 vw/vh 完全解析

155 阅读4分钟

vw(Viewport Width)和 vh(Viewport Height)是 CSS 中基于浏览器可视视口的相对长度单位,核心优势是能直接适配不同屏幕尺寸,是响应式布局的核心工具之一。

一、核心概念:视口与单位定义

1. 视口(Viewport)

指浏览器的可视区域尺寸(不包含浏览器的地址栏、工具栏、滚动条,移动端需注意 meta 视口标签的配置),是 vw/vh 计算的基准。

  • 桌面端:视口 = 浏览器窗口的可视宽 / 高;
  • 移动端:默认 “布局视口” 远大于屏幕,需通过 <meta name="viewport" content="width=device-width, initial-scale=1.0"> 让布局视口等于 “视觉视口”(屏幕可视区域)。

2. vw/vh 定义

  • vw:1vw = 视口宽度的 1%;
  • vh:1vh = 视口高度的 1%。
示例计算

若浏览器可视宽度为 1920px → 1vw = 1920 × 1% = 19.2px;若浏览器可视高度为 1080px → 1vh = 1080 × 1% = 10.8px;若移动端屏幕宽 375px → 1vw = 3.75px;高 667px → 1vh ≈ 6.67px。

二、核心特点(与其他单位的区别)

1. 对比百分比(%)

% 是相对于父元素的尺寸,而 vw/vh 是相对于视口的尺寸,这是最核心的区别:

/* 示例:父元素宽 200px,视口宽 1920px */
.parent { width: 200px; }
.child-1 { width: 50%; } /* 宽度=200×50%=100px */
.child-2 { width: 50vw; } /* 宽度=1920×50%=960px */

2. 对比 px(绝对单位)

px 是固定值,无法适配不同屏幕;vw/vh 随视口实时变化,天然适配响应式,无需媒体查询。

3. 关键特性

实时响应:视口尺寸变化(如浏览器窗口缩放、手机旋转)时,vw/vh 元素尺寸自动更新;

无继承性:尺寸仅依赖视口,与父元素、祖先元素无关;

兼容性:现代浏览器(Chrome/Firefox/Safari/Edge)均支持,IE11 部分支持(无 vmin/vmax,但 vw/vh 可用)。

三、常用补充视口单位

除了 vw/vh,还有两个高频衍生单位:

单位 定义 适用场景

vmin 取 vw 和 vh 中的较小值 适配横竖屏(如正方形元素,避免旋转后超出屏幕)

vmax 取 vw 和 vh 中的较大值 全屏覆盖(如弹窗背景,确保横竖屏都占满)

/* 横竖屏都保持正方形(边长为屏幕短边的80%) */
.square {
  width: 80vmin;
  height: 80vmin;
  background: #000;
}

四、实际应用场景(附代码示例)

  1. 全屏布局(最常用)

实现登录页、落地页的全屏背景 / 容器,无需计算固定 px:

/* 全屏背景容器 */
.full-screen {
  width: 100vw;
  height: 100vh;
  background: url(bg.jpg) center/cover no-repeat;
}

/* 全屏按钮(宽度占视口80%,高度占视口10%) */
.full-btn {
  width: 80vw;
  height: 10vh;
  font-size: 3vw; /* 文字随屏幕缩放 */
}

2. 响应式文字大小

替代固定 px,避免移动端文字过大 / 过小,结合 clamp() 可限制范围(推荐):

/* 文字最小16px,最大24px,中间随vw缩放 */
.text {
  font-size: clamp(16px, 3vw, 24px);
}

3. 适配不同设备的容器

移动端卡片、模块宽度按 vw 设置,适配所有手机屏幕:

/* 移动端卡片(左右留5vw间距,宽度90vw) */
.card {
  width: 90vw;
  margin: 0 auto;
  padding: 2vw;
  font-size: 2.5vw;
}

4. 结合 calc () 精细控制

搭配 calc() 实现 “视口占比 + 固定间距” 的布局:

/* 宽度=视口70% - 20px,高度=视口50% + 10px */
.box {
  width: calc(70vw - 20px);
  height: calc(50vh + 10px);
}

五、注意事项

  1. 移动端视口适配

必须添加 meta 视口标签,否则布局视口默认是 980px,vw/vh 计算会失真:

<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">

2. 滚动条的影响

  • 桌面端:部分浏览器(如 Chrome)的滚动条会占用视口宽度,导致 100vw 略大于可视区域(可通过 overflow: hidden 或适配滚动条样式解决);
  • 移动端:无滚动条(滚动时为悬浮式),无此问题。

3. 避免过度依赖

  • vh 在移动端存在 “地址栏收缩” 问题(如微信浏览器滚动时,地址栏隐藏,视口高度变化,导致 100vh 元素跳动),可改用 min-height: 100dvh(dvh 是动态视口单位,适配地址栏变化);

  • 文字大小若纯用 vw,小屏可能过小,大屏过大,务必结合 clamp() 限制范围。

  1. 兼容性

浏览器 支持情况

Chrome/Firefox/Safari/Edge 完全支持

IE11 支持 vw/vh,不支持 vmin/vmax

移动端浏览器(微信 / 支付宝) 完全支持

六、总结

vw/vh 是响应式布局的 “利器”,核心价值是脱离父元素依赖,直接基于视口适配

  • 适合场景:全屏布局、响应式文字、移动端适配;
  • 避坑点:移动端加 meta 标签、用 dvh 替代 vh 解决地址栏问题、文字搭配 clamp ();
  • 核心区别:% 相对父元素,vw/vh 相对视口。

合理使用 vw/vh 可大幅减少媒体查询的编写,让布局更简洁、适配更自然。