必须用JS监听scroll事件更新--stop变量,再通过linear-gradient(to right, #ff6b6b, #4ecdc4 var(--stop), #44b5b1)动态控制色标位置,配合background-clip: text和color: transparent实现文字渐变滚动效果。

用 scrollY 动态更新 --text-gradient-stop CSS 变量
纯 CSS 无法读取滚动位置,必须靠 JS 监听 scroll 事件并写入自定义属性。关键不是“让渐变动起来”,而是把滚动值映射成一个可控制的色标位置(比如 linear-gradient(to right, #f00, #00f) 中第二个颜色的起始点)。推荐在 :root 或目标元素上设置一个变量,如 --stop,JS 每次滚动时更新它。
- 不要直接操作
style.background—— 难维护、无法复用、破坏 CSS 变量设计意图 - 避免高频触发重绘:用
requestAnimationFrame节流,或至少用throttle包裹scroll回调 - 映射公式建议用
Math.min(Math.max(scrollY / 100, 0), 1),把滚动距离归一化到[0, 1]区间,安全用于color-stop
linear-gradient 里怎么用 CSS 变量控制色标位置
CSS 变量可以出现在 linear-gradient() 的任意位置,包括色标偏移值,但必须确保变量是数值且单位合法(如 %、px、无单位小数)。不能写成 var(--stop) 单独作参数,而要嵌入到函数内部。
:root {
--stop: 50%;
}
h1 {
background: linear-gradient(to right, #ff6b6b, #4ecdc4 var(--stop), #44b5b1);
-webkit-background-clip: text;
background-clip: text;
color: transparent;
}
- 上面例子中,当
--stop是30%,中间色就在 30% 处开始过渡;设为70%就右移 —— 文字颜色“重心”随滚动偏移 - Chrome/Firefox/Safari 均支持变量在
linear-gradient内使用,但旧版 Safari(≤15.4)对var()在渐变中的解析有 bug,建议加降级色:background: #4ecdc4; - 不要写
var(--stop)%—— 这会报语法错误;变量本身应包含单位,或用calc(var(--stop) * 1%)转换
为什么 background-clip: text + color: transparent 是必要组合
渐变生效的前提是文字本身“透出”背景。仅设 background-image 不够,必须配合裁剪和透明色,否则看到的是块级背景色而非文字轮廓内的渐变。
-
-webkit-background-clip: text是 Safari/Chrome 必需前缀,不加则渐变不贴合文字形状 -
background-clip: text是标准属性,Firefox 110+ 支持,但低版本仍需前缀 -
color: transparent不可省略 —— 如果文字有默认色(如黑色),会盖住背景,渐变不可见 - 注意:该组合在部分安卓 WebView(如微信内核)中失效,需检测
background-clip支持性并 fallback 到单色
滚动监听中容易漏掉的兼容细节
不同设备滚动源不同(body vs documentElement),且 iOS Safari 有弹性滚动回弹行为,scrollY 可能为负或超限。直接取 window.scrollY 在某些场景下不准。
立即学习“前端免费学习笔记(深入)”;
function updateGradientStop() {
const y = window.scrollY || document.documentElement.scrollTop;
const stop = Math.min(Math.max(y / (document.body.scrollHeight - window.innerHeight), 0), 1);
document.documentElement.style.setProperty('--stop', `${stop * 100}%`);
}
window.addEventListener('scroll', () => {
requestAnimationFrame(updateGradientStop);
});
- 用
document.documentElement.scrollTop兼容 IE 和部分移动端 scroll 不触发window.scrollY的情况 - 分母用
document.body.scrollHeight - window.innerHeight算出最大可滚动距离,比固定除数更鲁棒 - iOS 上快速滚动可能触发多次
scroll,但requestAnimationFrame保证每帧只执行一次更新,避免样式抖动 - 如果页面有 fixed header,记得从
scrollY中减去其高度,否则渐变起始点会错位
CSS 变量 + 渐变 + 滚动联动看似简单,真正卡住人的往往是 scrollY 获取不准、单位拼接错误、或忘了 background-clip 的浏览器前缀。动手前先确认目标环境是否支持 background-clip: text,再决定要不要加 polyfill。










