视口单位换算
vw / vh / vmin / vmax / vb / vi / svh / lvh / dvh / svw / lvw / dvw 的语义说明与像素换算:输入视口宽高算出具体 px,并解释移动端 100vh 问题与 svh / lvh / dvh 的取舍。
浏览器本地运行所有计算都在你的浏览器里完成,数据不会离开本机。
视口尺寸
vw / vh 基于大视口(浏览器 UI 收起时的尺寸),所以移动端 100vh 会高于可见区域;svh 取最小高度、dvh 取当前可见高度、lvh 与 vh 相同。
实时预览
预览按比例画出三种视口高度:虚线是当前可见高度(dvh),灰底是浏览器 UI 展开时的最小高度(svh)。
结果
| 单位 | 1 单位 | 100 单位 | 该数值 |
|---|---|---|---|
| vw | 3.9px | 390px | 195px |
| vh | 8.44px | 844px | 422px |
| vmin | 3.9px | 390px | 195px |
| vmax | 8.44px | 844px | 422px |
| vi | 3.9px | 390px | 195px |
| vb | 8.44px | 844px | 422px |
| svh | 7.8px | 780px | 390px |
| lvh | 8.44px | 844px | 422px |
| dvh | 8.1px | 810px | 405px |
| svw | 3.9px | 390px | 195px |
| lvw | 3.9px | 390px | 195px |
| dvw | 3.9px | 390px | 195px |
同一个全屏元素用四种写法的实际像素高度,以及与大视口高度的差值。
| 写法 | 高度 | 比大视口矮 |
|---|---|---|
| 100vh | 844px | 0px |
| 100svh | 780px | 64px |
| 100lvh | 844px | 0px |
| 100dvh | 810px | 34px |
:root {
--vw: 3.9px; /* 1vw */
--vh: 8.44px; /* 1vh = 1lvh */
--svh: 7.8px; /* 1svh */
--dvh: 8.1px; /* 1dvh */
}.hero {
/* fallback: always fully visible */
height: 100svh;
/* when dynamic viewport units are supported, hug the visible area */
height: 100dvh;
}:root {
--app-height: 780px;
}
.hero {
height: var(--app-height, 100vh);
}svh / lvh / dvh 怎么选
| 单位 | 优点 | 缺点 | 适合 |
|---|---|---|---|
| vh | 兼容性最好,桌面端数值稳定,不会随滚动变化。 | 等于大视口高度,移动端浏览器工具栏展开时底部会被遮住,100vh 通常比可见区域高几十像素。 | 桌面端全屏区块,或已经用 svh 兜底时的降级写法。 |
| svh | 永远完整可见,不会随工具栏展开/收起跳动。 | 取的是最小高度,工具栏收起时底部会留出空白。 | 首屏内容必须全部看到的场景:引导页、登录页、按钮不能被遮挡的表单。 |
| lvh | 最大高度,视觉上铺满屏幕。 | 与 vh 一样会被工具栏遮住,滚动到底部可能发现内容被挡住。 | 背景、装饰性大图这类「被遮一点也无所谓」的元素。 |
| dvh | 始终等于当前可见高度,视觉上最精确。 | 滚动时高度会变,可能引起重排与抖动,性能敏感的场景要谨慎。 | 全屏弹窗、抽屉、视频容器等必须贴合可见区域的元素。 |
单位参考
| 单位 | 基准 | 该数值 |
|---|---|---|
| vw | 视口宽度 | 视口宽度 1% · 1vw = 布局视口宽度 ÷ 100,等同 lvw。 |
| vh | 视口高度 | 视口高度 1% · 1vh = 大视口高度 ÷ 100(等同 lvh)。移动端 100vh 高于可见区域,会出现页面被浏览器工具栏遮住的问题。 |
| vmin | 视口较小边 | 视口较小边 1% · 1vmin = min(宽, 高) ÷ 100,横竖屏切换时更稳定。 |
| vmax | 视口较大边 | 视口较大边 1% · 1vmax = max(宽, 高) ÷ 100。 |
| vi | 视口宽度 · 跟随书写方向 | 书写方向上的行内尺寸 1% · 跟随书写方向:横排时 vi = vw,竖排时 vi = vh。 |
| vb | 视口高度 · 跟随书写方向 | 书写方向上的块级尺寸 1% · 跟随书写方向:横排时 vb = vh,竖排时 vb = vw。 |
| svh | 视口高度 | 小视口高度 1% · 浏览器 UI 完全展开时的高度,永远完整可见,适合首屏必须全部看到的内容。 |
| lvh | 视口高度 | 大视口高度 1% · 浏览器 UI 收起时的高度,与 vh 等价,最大但可能被工具栏遮住一部分。 |
| dvh | 视口高度 · 随 UI 动态更新 | 动态视口高度 1% · 当前可见高度,随 UI 展开/收起实时变化,最贴合实际可见区域,但滚动时元素高度会变化。 |
| svw | 视口宽度 | 小视口宽度 1% · 视口宽度最小时的 1%,仅在宽度本身会变化时与 vw 不同。 |
| lvw | 视口宽度 | 大视口宽度 1% · 视口宽度最大时的 1%,通常与 vw 相同。 |
| dvw | 视口宽度 · 随 UI 动态更新 | 动态视口宽度 1% · 当前视口宽度的 1%,宽度变化(例如叠加滚动条出现)时实时更新。 |
这个工具能做什么
- 写全屏区块前先算清楚:视口 390 × 844、地址栏展开时可见 780px,工具直接给出 100vh = 844px、100svh = 780px 的差距,知道底部会被遮多少。
- 把设计稿的像素值换成视口单位:50vh 在 844px 高的视口里是 422px,配合 vmin / vmax 还能写出随屏幕比例缩放的标题字号。
- 排查移动端「页面能上下滑一点」的问题:多半是 100vh 比可见区域高,换成 svh 或 dvh 即可解决。
- 给团队写规范时引用取舍表:什么时候用 svh、什么时候用 dvh、什么时候继续用 vh,连同优缺点一起说清楚。
示例
输入
视口宽度 390px、大视口高度 844px、小视口高度 780px、当前可见高度 810px,换算 50vh
输出
1vh = 8.44px,50vh = 422px;100vh = 844px、100svh = 780px(比大视口矮 64px)、100dvh = 810px(比大视口矮 34px)
移动端 100vh 之所以溢出,就是因为 vh 取的是大视口高度而不是当前可见高度。
常见问题
为什么移动端 100vh 会出现滚动条?
规范里 vh 对应大视口高度,也就是浏览器地址栏收起时的尺寸。地址栏展开时可见区域更小,100vh 的元素就比屏幕高,于是出现几十像素的滚动。用 100svh 保证完整可见,或用 100dvh 跟随当前可见高度即可解决。
svh、lvh、dvh 到底该选哪个?
首屏内容必须全部看到(登录页、引导页)用 svh,永远不溢出;需要贴合当前可见区域(全屏弹窗、抽屉、视频容器)用 dvh,代价是滚动时高度会变、可能引起重排;背景、装饰性大图用 lvh 铺满屏幕即可,被遮一点无妨。常用写法是先写 svh 兜底,再写 dvh 覆盖。
vw 和 svw / lvw / dvw 有什么区别?
它们只在视口宽度本身会变化时才有差别:叠加式滚动条出现/消失、可折叠侧栏、某些移动端浏览器的横向 UI。绝大多数场景下四者数值相同,所以只需要记住 vw,特殊布局再用 lvw / dvw。
vi 和 vb 是什么?
vi / vb 是逻辑方向上的视口单位:横排文本里 vi 等于 vw、vb 等于 vh;竖排文本(writing-mode: vertical-rl)里互换。做国际化排版时用它们可以避免写两套样式。
视口单位能拿来做字号吗?
可以,但要注意可访问性:纯 vw 字号会随屏幕宽度无限放大或缩小,用户无法通过放大页面调整。常见做法是用 clamp(1rem, 2vw + 0.5rem, 2rem) 这类组合,让字号在上下限内平滑变化,同时保留用户缩放的空间。
关键词:viewport unitsvw vhdvhsvhlvh100vh mobile视口单位视口换算100vh 问题移动端适配vw vh 换算响应式