scroll-behavior: smooth 不支持 css 变量,因其是浏览器原生滚动开关,仅接受 auto/smooth 字面值,解析即固化,不参与级联;动态控制需 js 切换 class 触发样式。

scroll-behavior: smooth 本身不接受 CSS 变量,也不支持动画缓动曲线自定义——它只有 auto 和 smooth 两个字面值,浏览器内部用固定贝塞尔曲线(如 cubic-bezier(0.2, 0.6, 0.4, 1))实现,无法通过 --scroll-easing 这类变量控制。
为什么 scroll-behavior 不支持 CSS 变量
该属性是浏览器原生滚动行为开关,不是 CSS 动画属性。它的值在解析时即被固化为布尔式指令(启用/禁用平滑),不参与级联、不响应 :root 变量变更,也无法被 @media 或 @supports 动态切换。即使你写成 scroll-behavior: var(--smooth, smooth);,所有主流浏览器(Chrome 128+、Firefox 129+、Safari 17.6+)都会忽略并回退到 auto。
想动态控制平滑滚动?只能靠 JS 切换 class
真正可操作的方案是用 JS 控制一个 class,再让该 class 触发或禁用 scroll-behavior:
- 在
:root或html上定义基础样式:html { scroll-behavior: smooth; } - 添加降级 class:
html.no-smooth { scroll-behavior: auto !important; } - 运行时根据偏好切换:
document.documentElement.classList.toggle('no-smooth', window.matchMedia('(prefers-reduced-motion: reduce)').matches) - 注意:不能只监听
change事件,iOS Safari 和微信 X5 WebView 可能不触发,建议在scroll或DOMContentLoaded后主动检测一次
scroll-margin-top 能用变量,但有兼容性陷阱
虽然 scroll-behavior 本身不可变,但配套的 scroll-margin-top 支持 CSS 变量,可用于适配不同导航高度:
h2[id] {
scroll-margin-top: clamp(50px, var(--nav-height, 60px), 80px);
}
但要注意:
- Safari ≤15.3 完全不支持
scroll-margin-top,哪怕用了变量也白搭 -
clamp()在 Safari 15.4+ 才稳定,旧版会 fallback 到第一个值 - 变量必须在 :root 中定义,且不能依赖 JS 动态改
style.setProperty后立刻生效——scroll-margin-top的计算发生在布局阶段,异步更新可能错过时机
真正需要“更平滑”,不是调参数,而是避开浏览器硬限制:iOS Safari 旧版、X5 内核、prefers-reduced-motion 开启时,scroll-behavior 会静默失效,此时必须用 element.scrollIntoView({ behavior: 'smooth' }) 配合 requestAnimationFrame 补偿,而不是幻想用变量绕过底层限制。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











