
本文介绍如何基于原生 JavaScript 与现代 CSS(conic-gradient + CSS 自定义属性)实现一个随页面滚动动态填充的圆形进度环,替代复杂 SVG 方案,代码简洁、性能优异且完全兼容现有逻辑。
本文介绍如何基于原生 javascript 与现代 css(`conic-gradient` + css 自定义属性)实现一个随页面滚动动态填充的圆形进度环,替代复杂 svg 方案,代码简洁、性能优异且完全兼容现有逻辑。
在已有滚动进度计算逻辑基础上,我们可彻底摒弃 SVG,转而使用 CSS 的 conic-gradient 创建动态环形进度指示器。其核心思想是:将一个完整圆周(360°)按滚动百分比(0–1)进行角度分割,用实色段表示已滚动部分,透明段表示剩余部分,并通过伪元素遮罩形成“环形”视觉效果。
✅ 关键实现要点
-
滚动百分比标准化:
getScrollPercent()返回0–1范围内的小数(非0–100),便于直接参与calc(360deg * var(--scrollPercent))计算; -
CSS 变量驱动:通过
element.style.setProperty('--scrollPercent', value)动态更新自定义属性,触发conic-gradient重绘; -
双层叠加结构:
-
#scroll-line:外层,使用conic-gradient绘制 360° 进度弧; -
#scroll-line::before:内层遮罩,背景色与主体#body_box一致(var(--bg)),尺寸略小,营造“空心环”效果;
-
-
居中与比例控制:借助
aspect-ratio: 1、transform: translate(-50%, -50%)确保精准居中与正圆渲染。
? 完整代码示例
<div class="content-site"></div>
<footer>
<div id="main_box">
<div id="body_box">
<div id="scroll-line"></div>
<p id="progress"></p>
</div>
</div>
</footer>.content-site { height: 500vh; }
#main_box {
position: fixed;
right: 50px;
bottom: 80px;
}
#body_box {
--bg: #b0ffcb;
width: 100px;
height: 100px;
background: var(--bg);
box-shadow: 0 0 4px #050030;
border-radius: 50%;
position: relative;
overflow: hidden;
}
#progress {
position: absolute;
top: 40%;
left: auto;
z-index: 3;
color: #f00;
margin: 0 auto;
width: 100%;
text-align: center;
font-weight: bold;
}
#scroll-line {
--scrollPercent: 0;
width: 100%;
height: 100%;
position: absolute;
top: 0; left: 0;
z-index: 2;
background: conic-gradient(
black 0deg,
black calc(360deg * var(--scrollPercent)),
transparent calc(360deg * var(--scrollPercent)),
transparent 360deg
);
border-radius: 50%;
/* 使用 aspect-ratio 替代固定宽高,更健壮 */
aspect-ratio: 1;
}
#scroll-line::before {
content: "";
display: block;
width: calc(100% - 15px);
height: calc(100% - 15px);
background: var(--bg);
border-radius: 50%;
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
}function getScrollPercent() {
const { clientHeight, scrollTop, scrollHeight } = document.documentElement;
return Math.max(0, Math.min(1, scrollTop / (scrollHeight - clientHeight)));
}
function update_scroll() {
const scrollPercent = getScrollPercent();
document.getElementById("scroll-line").style.setProperty("--scrollPercent", scrollPercent);
document.getElementById("progress").textContent = Math.round(scrollPercent * 100) + '%';
}
window.addEventListener("scroll", update_scroll);
update_scroll(); // 初始化⚠️ 注意事项
-
浏览器兼容性:
conic-gradient在 Chrome 85+、Firefox 83+、Safari 15.4+ 中原生支持;旧版需添加-webkit-conic-gradient前缀(本例未包含,如需兼容请自行补充); -
防抖优化(推荐):高频
scroll事件可能影响性能,建议用requestAnimationFrame或轻量防抖封装update_scroll; -
边界处理:
getScrollPercent()中增加了Math.max(0, Math.min(1, ...)),防止因 DOM 加载时序或缩放导致的异常值; -
环宽控制:环的粗细由
#scroll-line::before的width/height与外层差值决定(当前为15px),可自由调整。
该方案复用原有滚动监听逻辑,仅替换 UI 渲染层,零依赖、易维护、视觉表现专业,是现代 Web 进度环实现的理想选择。


















