应组合使用env(keyboard-inset-bottom)、visualviewport api和focusin/blur降级方案:ios 16.4+用bottom: env(keyboard-inset-bottom, 0px)配合viewport-fit=cover;现代浏览器监听visualviewport.resize计算键盘高度并translatey调整;旧版fallback至focusin/blur加settimeout延迟读取innerheight与getboundingclientrect动态定位。

不能只靠 position: fixed,iOS 和安卓对视觉视口(visual viewport)的处理不一致,键盘弹出时它会压缩或冻结,但 fixed 元素不重算位置——结果就是按钮飘在键盘上方、被顶出屏幕。纯 CSS 无解,必须组合环境变量、定位切换和 JS 监听。
用 env(keyboard-inset-bottom) 做 iOS 原生避让(16.4+)
这是目前最干净的方案,零 JS,但仅限 iOS Safari 16.4 及以上:
-
<meta name="viewport" content="width=device-width, initial-scale=1.0, viewport-fit=cover">必须加,否则不生效 - 写法是:
bottom: env(keyboard-inset-bottom, 0px);,0px是 fallback,不能省略 - 必须用
@supports (bottom: env(keyboard-inset-bottom))包裹,否则旧版 Safari 会忽略整条规则 - 安卓完全不支持,别和
svh混用,比如calc(0px + 100svh)是错的——svh是高度单位,env(keyboard-inset-bottom)是偏移量
用 visualViewport API 实时监听真实可视高度
比 resize 或 focusin 更准,能直接拿到键盘弹出后用户真正看到的高度:
- 页面加载时先存基准:
const baseHeight = visualViewport.height; - 监听:
visualViewport.addEventListener('resize', () => { const kbHeight = baseHeight - visualViewport.height; }) - 用
transform: translateY(${kbHeight}px)调整按钮位置,比改bottom更少触发重排 - 兼容性:Safari 15.4+、Chrome 61+、Edge 79+;老版本必须降级,不能只靠它
fallback 到 focusin/blur + setTimeout 动态计算
resize 在真机上基本不可靠(iOS 触发率 focusin 才是唯一稳定入口点:
- 监听所有可聚焦元素:
input、textarea、[contenteditable],别漏掉textarea -
focusin回调里必须加setTimeout(() => { /* 读坐标 */ }, 0),否则getBoundingClientRect().bottom还是弹出前的旧值 - 计算方式:
window.innerHeight - inputRect.bottom,不是写死数值 -
blur后立刻恢复position: fixed; bottom: 0,并调用el.style.removeProperty('top')和el.style.removeProperty('bottom')清除内联样式
为什么 position: absolute 不是“换个属性就完事”
只把 position: fixed 改成 absolute 会同样错位,因为 absolute 的定位基准是最近的 position: relative 祖先容器——如果这个容器本身高度不可控,它也会被键盘顶变形:
- 根容器(如
#app或body)必须设position: relative和min-height: 100vh(不能只写height: 100%,否则键盘弹出时塌陷) - 底部区域必须加
width: 100%,否则横屏或缩放后可能偏移 - 多个输入框共用同一底部栏?得用全局变量记录
document.activeElement,避免重复切换或漏恢复 - 别在
relative父级上加overflow: hidden或transform,否则getBoundingClientRect()返回错误坐标
真正难的不是写哪行 CSS,而是判断当前环境支持什么、降级路径是否闭环、blur 后有没有清掉所有残留样式——漏掉任意一环,按钮就会在某个机型上突然消失或卡在半空。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











