overflow-anchor:上方内容变高时别让画面乱跳
正读着文章中段,上方一张图片刚加载完、一段内容插了进来,整页内容下移——正在读的那行就突然往下跳。scroll anchoring(滚动锚定) 是浏览器的默认补偿:它悄悄选定视口里的一个锚元素,在上方高度变化时调整 scrollTop,让当前视线所及的内容留在原地。overflow-anchor
就是这套机制的开关。
1 · 两个值
auto(默认):参与滚动锚定,浏览器自动补偿。none:把某个子树 / 容器排除在锚定之外——主动退出,把滚动控制权交回给页面脚本。
2 · 上方插入内容时的位移
下框里有一行高亮的「👀 盯着这一行」。点「在顶部插入一段」,在它上方插入一块内容。切 overflow-anchor 各试一次,看那一行在视口里的位置变了多少。
3 · 隐形补偿的机制
开启锚定时,浏览器在每帧布局后选一个视口内的锚节点;当锚点之上的内容尺寸变化(图片加载、字体替换、广告注入、异步内容)导致它该移动时,浏览器反向调整滚动偏移把它拉回原位。这一切对页面脚本透明,所以平时根本不会注意到它在工作,直到它和页面自己的滚动逻辑相互冲突。
4 · 什么时候要主动关掉(none)
- 自己维护滚动位置时:无限滚动列表、聊天「加载更早的消息」往顶部追加内容,此时页面已用 JS 校正
scrollTop,锚定的补偿会与之叠加、相互冲突,设none交回控制权。 - 展开 / 折叠、轮播自动切换等动画里:锚定可能把页面往回拽,给这块容器设
none让它别管。
5 · 边界与细节
- 只补偿视口上方的尺寸变化;下方变化本来就不影响当前视图。
- 锚点由浏览器启发式选定,不能精确指定;能做的只有用
overflow-anchor: none局部退出。 -
和
overscroll-behavior名字像但毫不相关:前者管「上方变高时别跳」,后者管「滚到边界往哪传 / 回弹」。