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 名字像但毫不相关:前者管「上方变高时别跳」,后者管「滚到边界往哪传 / 回弹」。