如何为随页面滚动的圆形添加渐变背景线并实现指定覆盖效果
滚动跟随圆形与动态线条修复方案
需求回顾
需要实现一个跟随页面滚动的圆形,同时带出同色线条,效果要求:
- 圆形内部为白色
- 滚动至区块顶部/底部时,蓝色完全覆盖黄色背景线
- 滚动至区块中间位置时,圆形上下保留蓝色渐变过渡
当前实现中,使用::before伪元素的方案在滚动到顶部时仍有黄色残留,以下是修复方案:
核心修改思路
- 移除原有
::before伪元素的复杂阴影实现,改用背景渐变叠加的方式实现动态线条效果 - 让圆形的遮罩渐变与区块高度绑定,通过JS动态控制背景位置,实现滚动时的渐变范围适配
- 调整层级关系,确保圆形的白色内圈和蓝色渐变正确覆盖黄色线条
修改后完整代码
HTML
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/bootstrap/5.3.0/css/bootstrap.min.css" integrity="sha512-t4GWSVZO1eC8BM339Xd7Uphw5s17a86tIZIj8qRxhnKub6WoyhnrxeCIMeAqBPgdZGlCcG2PrZjMc+Wr78+5Xg==" crossorigin="anonymous" referrerpolicy="no-referrer"/> <div class="block1"></div> <div class="block2"> <div class="circle"></div> <div class="case"> <div class="row"> <div class="col-5 text">Text 1</div> <div class="col-2"></div> <div class="col-5 text">Text 1</div> </div> </div> <div class="case"> <div class="row"> <div class="col-5 text">Text 2</div> <div class="col-2"></div> <div class="col-5 text">Text 2</div> </div> </div> <div class="case"> <div class="row"> <div class="col-5 text">Text 3</div> <div class="col-2"></div> <div class="col-5 text">Text 3</div> </div> </div> </div> <div class="block3"></div>
CSS
.block1 { height: 200px; background-color: gray; } .block3 { height: 600px; background-color: gray; } .block2 { height: 100%; position: relative; /* 黄色背景线 */ background: linear-gradient(214deg, rgba(79, 142, 255, 0) 0%, #f5e550 10%, #f5e550 90%, rgba(79, 142, 255, 0) 100%) center/3px calc(100% - 100px) no-repeat; } .block2 .circle { position: absolute; width: 17px; height: 17px; left: 50%; transform: translate(-50%, -50%); border-radius: 50%; /* 蓝色外圈 */ background-color: #4f8eff; z-index: 2; } /* 白色内圈 */ .block2 .circle::before { content: ""; position: absolute; inset: 3px; border-radius: 50%; background-color: white; z-index: 1; } /* 动态蓝色渐变线条,随圆形位置调整 */ .block2 .circle::after { content: ""; position: absolute; left: 50%; transform: translateX(-50%); width: 3px; height: 100vh; /* 上下透明渐变,中间实色蓝色 */ background: linear-gradient(to bottom, rgba(79, 142, 255, 0), #4f8eff 40%, #4f8eff 60%, rgba(79, 142, 255, 0)); z-index: 0; top: calc(-50vh + 8.5px); } .text { text-align: center; padding: 200px 50px; }
JavaScript
const circle = document.querySelector(".circle"); const cases = document.querySelectorAll(".case"); const block2 = document.querySelector(".block2"); const handleScroll = () => { const { height: blockHeight } = block2.getBoundingClientRect(); // 计算圆形可移动的上下边界 const minTop = cases[0].offsetTop; const maxTop = cases[cases.length - 1].offsetTop + cases[cases.length - 1].offsetHeight - circle.offsetHeight / 2; // 计算当前滚动对应的圆形位置 const case1Top = cases[0].getBoundingClientRect().top + window.scrollY; const currentTop = Math.min(maxTop, Math.max(case1Top + cases[0].offsetHeight / 2, minTop)); // 设置圆形位置 circle.style.top = `${currentTop}px`; }; // 防抖处理滚动和窗口 resize 事件 let debounceTimer; const handleWindowEvents = () => { clearTimeout(debounceTimer); debounceTimer = setTimeout(handleScroll, 10); }; // 初始化与事件绑定 handleScroll(); window.addEventListener("scroll", handleWindowEvents); window.addEventListener("resize", handleWindowEvents);
效果说明
- 滚动到区块顶部时,圆形的蓝色渐变线条会完全覆盖上方黄色线条
- 滚动到区块底部时,下方黄色线条也会被完全覆盖
- 中间位置时,圆形上下会显示自然的蓝色渐变过渡,无黄色残留
内容的提问来源于stack exchange,提问作者Hector
相关产品推荐
相关产品推荐

