E4.19.4stable focus position across dialog resize设计研究

尺寸变化时已聚焦的元素位置不应跳变

别名: 对话框跳动 · 焦点跳走 · 尺寸变化 · layout shift in dialog

概念解释

对话框在打开之后仍可能改尺寸:校验多出一行、键盘顶起、语言切换、从卡片退到全屏。正在输入或正在看的那个字段,位置不该因此跳到别处甚至滚出视口。尺寸变、焦点位置稳(stable focus across resize)保的是正在进行的那一步还在手指和视线下,而不是整框重排完人要重新找光标。

机制

输入是盯着一个空间位置进行的。框一改高,若实现按「整体居中」重新算外沿,内容区的每一行都会相对视口移动,光标从键盘上方忽然跑到键盘下面,下一键打在错误字段上,或打在已经不是输入框的地方。内部滚动若在重排时把滚动偏移清零,正在填的字段会回到顶部以外。稳的做法是以当前焦点节点为锚:尺寸变化后,让该节点仍在可视区内的同一相对位置,必要时只动滚动偏移,而不是让整份内容跟着框的中心走。键盘弹出是最常见的尺寸事件,尤其要把焦点字段顶到键盘之上,但不能把整框连标题一起顶出视口。动画可以缓和位移,不能代替锚点——没有锚,动画只是把跳动放慢。

怎么研究

在聚焦某字段时触发尺寸变化:插入错误文案、弹出键盘、切换语言、旋转设备。记录焦点节点中心相对视口的位移、是否仍可见、是否误输入到邻字段。自变量:重排是否保持焦点锚、是否重置内部滚动。因变量:位移像素、丢失焦点、邻字段误输入。无锚的居中重排在键盘弹出时应位移最大。

边界

用户自己拖拽改变框大小,位移是预期内的,但仍应尽量让焦点字段留在框内。焦点在关闭按钮上时,内容区怎么滚都不影响输入,约束弱一些。第一次打开时的尺寸计算没有「已经在看的字段」,不存在跳变,这条管的是打开之后。屏幕阅读器不靠像素位置,但焦点对象若在重排中被销毁重建,朗读会中断,锚还要保住节点身份。

怎么落地

  • 任何会改框高的更新都以当前焦点节点为锚,保持它在可视区内。
  • 不要在内容更新时把内部滚动条打回顶部。
  • 键盘弹出时把焦点字段送到键盘上方,标题可压缩,不要把整框顶出屏幕。
  • 验证:在输入到一半时让错误信息出现或弹出键盘,光标应仍在刚才那个字段上且字段仍可见。要重新点一次才能继续打,就是跳了。

延伸

  • 同组E4.19.1 对话框尺寸应随内容量而非固定写死 · E4.19.2 窄屏下对话框常需退化为全屏展示 · E4.19.3 内容超出可视高度时需要内部滚动而非撑破弹层
  • 相邻E2.22 自动聚焦与焦点抢夺 · E4.10 模态对话框
  • 站内检索layout shift · focus stability · keyboard avoidance

同组卡片

快捷操作

分享

分享当前页面

ios_share

https://hci.top/zh/handbook/E4.19.4