弹出后可视区域压缩需重新布局而非简单上推
别名: 键盘 inset · 视口压缩 · visualViewport
概念解释
键盘弹出后,真正还能画界面的区域变矮了。正确的反应是按新的可视高度重新排:滚动容器变矮、粘性页眉和页脚决定去留、当前字段在剩余空间里找位置。把整页往上平移、高度仍按全屏算,叫简单上推——字段也许暂时露出来,标题、进度条或底部导航会被推出屏幕,或字段露了按钮仍留在键盘后面。
机制
系统提供的是一块 inset:布局视口可能不变,可见视口变了。上推等价于给根节点加一段平移,文档流的高度和粘性定位的参照都不更新,于是出现三层错位——固定顶栏跟着走或被顶没、position: fixed 的底栏仍贴在被挡的屏幕底、滚动范围仍包含键盘下面那截空白。重新布局把剩余高度当作新的包含块:主滚动区的 client height 减小,底栏改贴在键盘上沿,过高的卡片改成内部滚动。多字段表单尤其不能靠一次平移:上推对准了第三个字段,第一个的标签和进度指示就丢了。压缩之后的信息优先级要重算,不是把原布局整体挪地方。
怎么研究
对比三种策略:不处理、整页平移、按可见视口重排。记录字段可见、主按钮可见、页眉/进度是否还在、以及用户能否滚到其余字段。自变量包括字段数量、是否有粘性栏、键盘高度变化(候选栏展开);因变量包括可见关键控件集合和错误的滚动弹性(橡皮筋露底)。在模拟器里改窗口高度,与真机 inset 的时序并不相同,要用真机的键盘动画中途和结束后两帧。
边界
只有一两个字段、没有粘性栏的短页,上推有时够用。桌面窗口缩放不是键盘 inset,不能把这套重排套到桌面。悬浮键盘、可拖动的 iPad 键盘没有稳定的“底边”,重排锚点会不停变,可能要改成“不要重排、让用户自己把键盘拖开”。Web 里 vh 单位常仍按布局视口算,重排必须读可见视口而不是 CSS 的 100vh。
怎么落地
- 监听可见视口或系统 inset,把主滚动区高度和固定底栏的贴边改到键盘上沿,而不是给页面加 translateY。
- 压缩后保留任务进度或步骤标题;若空间不够,优先丢掉次要底栏,而不是丢掉当前字段的标签。
- 在键盘升起、候选栏展开、旋转三个时刻各截一帧,检查顶栏、当前字段、主按钮三者的可见组合,而不是只看升起瞬间字段是否露头。