H5 iOS 输入框唤起后 fixed 定位失效的纯 CSS 解法

· 进步分子, 投稿

AI 总结 · 连续创业者视角(以下内容由 AI 提炼,观点归原作者;读完可不看原文)

iOS 软键盘唤起时 fixed 元素会变为 absolute 并随页滚动,导致置顶/置底元素错位。解法是取消 body 滚动,将 main 区域改为 -webkit-overflow-scrolling: touch 独立滚动,从而保持 fixed 元素稳定。

  • 用 inner scroll 替代 body scroll 根治 fixed 失效
  • 添加 -webkit-overflow-scrolling…
  • 禁止 header/footer 的 touchmove 防浏览器全屏切换遮挡
  • 输入框 focus 时用 scrollIntoView 防止被键盘遮挡

核心解法:用 inner scroll 替代 body scroll

原理:iOS 软键盘唤起后,页面 fixed 会退化为 absolute。只要页面不再有整体滚动(body 固定),即使 fixed 失效,它也跑不掉。

关键 CSS:

  • main 区域(滚动容器):height: 100vh; overflow-y: auto; -webkit-overflow-scrolling: touch;
  • body:position: fixed; width: 100%;

完整实现方案

结构如下,header/footer 固定,main 内部滚动:

1. HTML 结构

<body>

  <div class="layout">

    <header class="fixed">...</header>

    <main class="scroll-area">...</main>

    <footer class="fixed">...</footer>

  </div>

</body>

2. 核心 CSS

body {

  position: fixed;

  width: 100%;

}

.layout {

  height: 100vh;

}

.scroll-area {

  height: 100%;

  overflow-y: auto;

  -webkit-overflow-scrolling: touch;

}

.fixed {

  position: fixed;

  left: 0; right: 0;

}

配套细节处理

  • 防键盘遮挡输入框:input focus 时调用 scrollIntoView({block: 'center'})
  • 防 touchmove 触发全屏:header/footer 禁止 touchmove 事件,避免浏览器地址栏/工具栏遮挡
  • 防页面露底:滚动到边缘时阻止默认行为
  • 第三方输入法兼容:iOS 第三方键盘常遮挡输入框,需在输入一条文字后重新计算位置(推断:这是 iOS WebView 的固有缺陷,无完美解法)

Android 适配

Android 2.3+ 不支持 -webkit-overflow-scrolling,但 body 滚动流畅,可直接用传统 fixed 方案。低于 2.3 需借助 isScroll.js。

可复现步骤

第一步:将 body 设为 fixed,内容容器 height 100vh

第二步:main 区域加 overflow-y: auto + -webkit-overflow-scrolling: touch

第三步:header/footer 用 fixed 定位,并禁止 touchmove

第四步:input focus 时调用 scrollIntoView,防止键盘遮挡

成本:纯 CSS,零依赖,修改量小,一个页面约 10 行 CSS 改动

原文 · 北门清燕:阅读原文 →

订阅《创造者日报》邮件版
每天精选可动手的搞钱机会、好用工具与稀缺观点,免费直达你的邮箱。
English reader? Subscribe the EN edition →
iMessage 邮件 联系我们
EN