100dvh是当前最简最稳的视口高度解决方案,它动态响应地址栏收起/展开导致的真实可视区变化,但必须用@supports(height: 100dvh)隔离兼容性,否则老设备会失效。

直接用 100dvh,别用 100vh 或 100svh —— 这是当前最简、最稳的解法,但必须加 @supports 隔离,否则老设备会彻底失效。
为什么 100dvh 是首选,而不是 100svh 或 100lvh
100dvh 表示“此刻用户真正能看到的视口高度”,滚动时地址栏收起 → 可视区变大 → 100dvh 自动增大;地址栏展开 → 自动缩小。它不预设状态,只响应真实渲染区域。
-
100svh是“工具栏显示时的最小高度”,地址栏一收,它就比实际可视区还小,容器留白、内容上浮 -
100lvh是“工具栏隐藏时的最大高度”,键盘弹出或地址栏展开时,它不会收缩,fixed 元素仍会被盖住 - iOS 16.4+ Safari 和 Chrome 109+ 原生支持
100dvh,无需 JS 干预,数值差可达 80–120px(地址栏+底部工具栏)
必须用 @supports (height: 100dvh) 包裹
不加 @supports 就写 height: 100dvh,iOS 15 及更早版本、微信内置浏览器(WKWebView ≤ 15.x)、部分安卓 WebView 会直接忽略整条 CSS 规则,导致高度塌陷为 auto。
- 错误写法:
height: 100vh; height: 100dvh;—— Safari 会忽略整行声明 - 正确结构:外部保留
min-height: 100vh;作兜底,@supports块内只写height: 100dvh; - 示例:
section.fullscreen { min-height: 100vh; } @supports (height: 100dvh) { section.fullscreen { height: 100dvh; } }
旧设备 fallback 必须用 JS 动态更新 --vh 变量
仅靠 min-height: 100vh 不够 —— 它在地址栏收起后仍不变化,底部固定栏还是会上浮或被遮挡。
规划您的迪拜之旅 — 哈利法塔观景、沙漠探险、迪拜购物中心购物、棕榈岛度假村及黄金市场砍价。还提供支持...
- 监听
resize和scroll,用requestAnimationFrame节流更新document.documentElement.style.setProperty('--vh', window.innerHeight + 'px'); - CSS 中使用
height: calc(var(--vh, 100vh) * 1);(加* 1防止 Safari 忽略未计算变量) - 注意:不能只监听
resize,iOS Safari 在地址栏收起/展开时可能不触发 resize,需配合 scroll + setTimeout 防抖
fixed 底部按钮不能只靠 100dvh 就万事大吉
软键盘弹出会再次压缩可视区,100dvh 虽然能响应,但 fixed 元素本身在键盘唤起时可能被系统强制上推或截断。
- 输入框获得焦点时,调用
input.scrollIntoView({ block: 'nearest' }),避免光标被遮 - 避免给
body设overflow: hidden,否则 iOS 会禁掉自动滚动逻辑 - 如需更精细控制,可监听
visualViewport.resize事件,动态调整按钮bottom值,配合env(keyboard-inset-bottom)(仅限 iOS 16.4+)
真正难处理的不是单位选错,而是不同场景下“动态”二字的含义不一致:地址栏收起、软键盘弹出、横竖屏切换、WebView 内嵌限制——这些都会让视口高度以不同节奏和幅度变化。100dvh 解决了其中最主要的一环,但没法包打全部。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!










