用径向渐变平铺实现小圆点装饰,轻量自适应;进度填充用CSS变量+calc()驱动linear-gradient或transform: scaleX(),避免background动画卡顿。
用径向渐变画小圆点,别用一堆
标签
很多同学一看到带装饰点的进度条,第一反应是写十个
,再用
均分——能跑,但 DOM 膨胀、语义混乱、缩放后圆点间距还容易错乱。真正轻量且自适应的方式是用 CSS 径向渐变平铺:
。这个渐变本质就是一个“左偏 8px、垂直居中、半径 2px 的白色实心圆”,配合
控制平铺间距,就能自动填满整个容器宽度。
圆点位置由
决定,X 是圆心距左侧距离,不是圆点直径
必须动态计算,比如
时,间距应为
(减去首尾两个圆心偏移)
别把
写死成
,否则在窄屏下会溢出或挤压变形
渐变色本身不参与进度逻辑,它只是轨道装饰;实际进度仍需靠另一个元素(如
)用
或
控制
做填充色,百分比得靠 JS 注入变量
想让渐变“停”在某个百分位(比如 65% 处截断),不能只写
——这会让颜色硬切,且 65% 是写死值,无法响应实时变化。正确做法是把进度值抽成 CSS 变量:
,然后在背景中用
拼接:
必须写
,不能省略
,否则浏览器当无单位数字处理,渐变失效
JS 更新时要用
(注意:这里传纯数字,不带
)
如果直接写
,再在 CSS 里用
,会导致语法错误——CSS 变量值带单位时,
里不能再乘
这种方案在 Safari 15.4+ 和 Chrome 100+ 稳定,但 IE 完全不支持,降级需回退到传统
方案
为什么不用
动态推渐变?
有人试过用
配合一个超宽渐变图(比如 1000px 宽的左右双色条)来模拟进度,理论上可行,但实际踩坑多:
渐变背景图宽度必须远大于容器,否则
推到尽头就露底色
移动端缩放或字体变化时,
里的百分比基准会随视口抖动,导致进度“跳帧”
安卓旧 WebView 对
+
组合支持不稳定,常卡在初始位置不动
性能上不如直接改
或
,因为
触发的是重绘(repaint),不是合成层加速(compositor)
动画卡顿?优先换
,别硬推
渐变做进度填充时,如果加了
,多数情况会掉帧,尤其在低端 Android 机上。根本原因是背景渐变动画无法走 GPU 合成,每次变化都触发整层重绘。更稳的解法是:把渐变画在伪元素上,用
缩放它。
使用HTML,CSS,JavaScript开发Android应用程序 英文文字pdf版附源文件
如果你了解HTML,CSS和JavaScript,您已经拥有所需的工具开发Android应用程序。本动手本书展示了如何使用这些开源web标准设计和建造,可适应任何Android设备的应用程序 - 无需使用Java。您将学习如何创建一个在您选择的平台的Android友好的网络应用程序,然后转换与自由PhoneGap框架到一个原生的Android应用程序。了解为什么设备无关的移动应用是未来的潮流,并开始构建应用程序,提供更
下载
立即学习
“
前端免费学习笔记(深入)
”;
走合成层,不触发布局(layout)和重排(reflow),60fps 更有保障
务必设
,否则缩放中心默认在中间,进度会从中间向两边展开
JS 控制时,直接操作
,比反复 setProperty 更快
注意:
会让伪元素完全不可见,若需显示 0% 状态,建议用
单独控制显隐
渐变实现自适应进度条最易被忽略的一点:它从来不是独立解决方案。你总得搭配一个真实反映数据的机制——要么用 JS 实时写
,要么用变量驱动
,要么用
映射比例。渐变本身只是“画布”,不是“控制器”。
flexbackground: radial-gradient(circle at 8px 50%, #fff 2px, transparent 2px)background-sizecircle at Xpx 50%background-size--total: 12calc((100% - 16px) / (var(--total) - 1))background-size40px 100%.progress-barwidthtransformlinear-gradientlinear-gradient(to right, #007BFF 65%, #eee 65%)--progress: 65calc()background: linear-gradient(
to right,
#007BFF calc(var(--progress) * 1%),
#eee calc(var(--progress) * 1%)
);calc(var(--progress) * 1%)* 1%el.style.setProperty('--progress', progress)%el.style.setProperty('--progress', progress + '%')var(--progress)calc()1%widthbackground-positionbackground-position: calc(var(--progress) * 1%) 0background-positioncalc()background-positioncalc()widthtransform: scaleX()background-positiontransformbackgroundtransition: background 0.3s easetransform: scaleX().progress-track::before {
content: '';
position: absolute;
top: 0; left: 0; bottom: 0;
width: 100%; height: 100%;
background: linear-gradient(to right, #007BFF, #eee);
transform-origin: left;
transition: transform 0.3s ease-out;
}
.progress-track.active::before {
transform: scaleX(0.65);
}transformtransform-origin: leftel.style.transform = 'scaleX(' + progress/100 + ')'scaleX(0)opacity: 0style.widthcalc()transform