一聚教程网:一个值得你收藏的教程网站

最新下载

热门教程

如何用CSS动态视口单位适配手机浏览器

时间:2026-08-17 12:38:48 编辑:袖梨 来源:一聚教程网

100dvh能动态适配视觉视口高度,解决软键盘弹出、分屏等场景下100vh内容遮挡或留白问题,但需@supports检测并兼容旧版iOS Safari的JS fallback方案。

直接用 100dvh 就能解决大部分手机浏览器的全屏高度适配问题,但必须确认目标环境支持——Chrome 100+、Firefox 103+、Safari 16.4+ 才原生支持 dvh;iOS Safari 16.4 之前仍得靠 JS 补救。

为什么不能继续用 100vh 做全屏高度

iOS Safari 和部分 Android 浏览器在软键盘弹出时,100vh 仍按「布局视口」计算,而实际可视区域被压缩,导致内容被遮挡或底部留白。这不是 bug,是规范行为:vh 绑定的是 layout viewport,不是用户真正看到的 visual viewport。

  1. 常见错误现象:height: 100vh 的登录页,键盘一弹,按钮就消失不见;固定定位的 footer 错位到屏幕中间
  2. Android 分屏/折叠屏下更糟:某些三星折叠屏展开后,100vh 仍按折叠态高度计算,造成大面积留白
  3. 不要给 <html><body> 直接设 height: 100vh,iOS 容易触发滚动异常

100dvh 是什么,怎么安全使用

dvh(dynamic viewport height)是 CSS Viewport Units Level 1 标准,表示「当前视觉视口高度的 1%」,能响应键盘弹出、地址栏收起、分屏等动态变化。

  1. 必须用 @supports 包裹,否则旧浏览器会忽略整条规则:
    @supports (height: 100dvh) {.full-screen {height: 100dvh;}}
  2. 降级 fallback 推荐写成:height: 100vh + min-height: 100dvh,避免旧版完全失效
  3. 优先作用于 wrapper 元素(如 <main>),而不是全局根元素

旧版 iOS Safari(<16.4)怎么补救

必须用 JS 动态监听并更新自定义 CSS 变量,且要防抖——Safari 的 resize 在键盘收起时可能连续触发 3–5 次。

  1. 核心代码:
    const updateVh = () => {document.documentElement.style.setProperty('--vh', `${window.innerHeight * 0.01}px`);};let resizeTimer;window.addEventListener('resize', () => {clearTimeout(resizeTimer);resizeTimer = setTimeout(updateVh, 50);});updateVh();
  2. CSS 中配合使用:height: calc(var(--vh, 1vh) * 100)
  3. 别忘了同时设 min-height: 100% 和父级 height: 100%,否则 calc() 在某些安卓 WebView 里不生效

混用 vw 和 vh 会导致比例失真

想让一个卡片在 iPhone 和 iPad 上都保持正方形?width: 50vw; height: 50vh 不行——因为不同设备宽高比差异太大,计算结果根本不是 1:1。

  1. 正确做法:改用 vmin,比如 width: 50vmin; height: 50vmin;,它取 vwvh 中较小值,天然保方
  2. 图标、头像容器、按钮尺寸这类需固定比例的场景,一律优先 vmin/vmax,而非混用 vw/vh
  3. 背景图、字体大小、横向滚动项这些单向依赖的场景,vwvh 单独用很安全

真正麻烦的从来不是写对那行 100dvh,而是忘记检查 Safari 版本、没加 @supports、或者在旧 iOS 上漏掉 resize 防抖——这三个点踩中任意一个,全屏页面就会在真实用户手里崩一次。

热门栏目