Safari 中 scroll-behavior: smooth 仅 iOS 15.4+/macOS 12.3+ 支持且仅对锚点链接生效;推荐优先使用 scrollIntoView({ behavior: 'smooth' }) 并校验元素可见性,辅以 scroll-margin-top 解决导航栏遮挡,避免 polyfill。

直接写 scroll-behavior: smooth 在 Safari 里大概率白写——不是你漏了分号,是 Safari(尤其 iOS 15.3 及更早)压根不实现这个 CSS 属性。
html { scroll-behavior: smooth } 是唯一能写的 CSS 写法
body 上设该样式无效,Safari 会静默忽略;页面级滚动容器是 html 元素,不是 body。但即使写对了,也只在 iOS 15.4+ / macOS 12.3+ 才开始解析,且仅对锚点链接(a[href^="#"])生效。
- 检查开发者工具的 Computed 样式中
scroll-behavior是否真为smooth,而非被重置规则覆盖 - 若用了全局 CSS 重置(如
* { margin: 0; }),留意是否意外清除了html的默认overflow或高度,导致它失去滚动能力 - 自定义滚动容器(如
div.overflow-auto)上写scroll-behavior: smooth,Safari ≤15.3 完全不支持,15.4+ 也仅限部分场景,建议放弃
scrollIntoView({ behavior: 'smooth' }) 必须显式传参才有效
Safari 对 scrollIntoView 的支持比 CSS 更早(iOS 15.4+ 已稳定),但有硬性条件:不传对象参数就退化为瞬时滚动,且不报错。
- 必须写成
el.scrollIntoView({ behavior: 'smooth', block: 'start' }),el.scrollIntoView(true)或el.scrollIntoView()都不会触发平滑 - 目标元素必须已渲染且可见:
el.offsetParent !== null且getComputedStyle(el).display !== 'none' - 避免用
block: 'nearest'—— Safari 中行为不稳定;固定定位容器内的元素可能计算偏移错误,建议先移出再滚动
锚点跳转后目标被导航栏遮住?加 scroll-margin-top
这不是 JS 错误,是浏览器把目标顶部对齐视口顶部,而 position: fixed 导航栏挡住了它。CSS 即可解决,无需 JS 计算 offset。
规划您的迪拜之旅 — 哈利法塔观景、沙漠探险、迪拜购物中心购物、棕榈岛度假村及黄金市场砍价。还提供支持...
立即学习“前端免费学习笔记(深入)”;
- 在目标元素上加
scroll-margin-top: 60px(值等于导航栏高度),推荐用px或clamp(50px, 8vh, 80px) - 别用百分比(
%),计算时机不稳定;scroll-margin-top只对锚点跳转和scrollIntoView()生效,对scrollTo()无效 - 勿混淆
scroll-padding-top—— 它作用于整个视口,不是锚点补偿
需要真正可控的滚动?手写 requestAnimationFrame 比 polyfill 更稳
引入 smooth-scroll-polyfill 在 Safari 中反而卡顿、偏移、堆叠动画帧,主因是其依赖 MutationObserver,而 Safari 的 layout timing 处理与其他浏览器不同。
- 手写逻辑核心三步:校验
el.offsetParent !== null、用el.getBoundingClientRect().top + container.scrollTop算目标位置、线性插值 +requestAnimationFrame增量更新container.scrollTop - 不要传绝对
scrollTop值,防止 Safari 回弹抖动;目标必须在明确设置了height和overflow: auto的父容器内 - 30 行内可覆盖 95% 场景,重点不在“怎么平滑”,而在“不出错”——比如连点时 cancel 前一个动画、不向不可见容器发起滚动
最易被忽略的一点:Safari 对滚动行为的支持不是“全有或全无”,而是按属性、按元素、按系统版本层层切片。写 @supports (scroll-behavior: smooth) 检测不可靠,它只查 CSS 是否被识别,不反映 JS 方法是否可用;真正要做的,是把 scrollIntoView 当作默认方案,把 CSS scroll-behavior 当作可选增强,而不是反过来。

















