仅用CSS或JS能否实现隐藏背景溢出的动态宽度分级进度条?
你的现有HTML结构无需修改,仅通过CSS即可实现目标效果,进度条宽度依然支持动态设置,修改后的实现方案如下:
CSS实现方案(推荐)
.average-rating * { box-sizing: border-box; } .average-rating { position: relative; width: 200px; height: 40px; /* 超出部分隐藏,避免进度条溢出 */ overflow: hidden; } .average-rating .progress { position: absolute; height: 100%; background-color: #66ff66; z-index: 1; /* 可选:添加过渡动画,进度变化更丝滑 */ transition: width 0.3s ease; } .average-rating .balls { position: relative; z-index: 2; display: flex; width: 100%; height: 100%; /* 核心:背景默认白色,通过mask属性在对应圆球位置挖透明洞,透出下方进度条 */ background: #fff; -webkit-mask-image: radial-gradient(circle at 10% 50%, transparent 17px, #000 17px), radial-gradient(circle at 30% 50%, transparent 17px, #000 17px), radial-gradient(circle at 50% 50%, transparent 17px, #000 17px), radial-gradient(circle at 70% 50%, transparent 17px, #000 17px), radial-gradient(circle at 90% 50%, transparent 17px, #000 17px); mask-image: radial-gradient(circle at 10% 50%, transparent 17px, #000 17px), radial-gradient(circle at 30% 50%, transparent 17px, #000 17px), radial-gradient(circle at 50% 50%, transparent 17px, #000 17px), radial-gradient(circle at 70% 50%, transparent 17px, #000 17px), radial-gradient(circle at 90% 50%, transparent 17px, #000 17px); } .average-rating .balls div { flex: 1; height: 100%; border-radius: 50%; border: 3px solid #006600; }
实现说明:
- 核心逻辑是通过mask属性给上层的
.balls容器挖5个和下方圆球位置完全对齐的透明洞,底层进度条的绿色只会从洞中透出,自然实现仅圆球内部填充进度的效果 - 17px是根据当前尺寸计算的圆球内部半径:总高度40px减去两侧3px边框,内部半径为
40/2 - 3 = 17px,如果你调整了组件尺寸修改这个数值即可 - 进度条宽度依然可以通过内联style、CSS变量或JS动态修改,不需要额外调整其他代码
JS兼容方案(适配不支持mask属性的旧浏览器)
如果需要兼容低版本浏览器,可以用JS直接给每个圆球设置填充比例,不需要修改现有CSS:
function updateRatingProgress(percent) { const ballItems = document.querySelectorAll('.average-rating .balls div') // 每个圆球对应总进度的20% const perBallRate = 100 / ballItems.length ballItems.forEach((ball, index) => { const currentBallStart = index * perBallRate const currentBallEnd = (index + 1) * perBallRate if (percent >= currentBallEnd) { // 进度完全覆盖当前球,全填充 ball.style.backgroundColor = '#66ff66' } else if (percent > currentBallStart) { // 进度部分覆盖当前球,按比例填充 const fillRate = ((percent - currentBallStart) / perBallRate) * 100 ball.style.background = `linear-gradient(to right, #66ff66 ${fillRate}%, transparent ${fillRate}%)` } else { // 进度未覆盖当前球,不填充 ball.style.backgroundColor = 'transparent' } }) } // 调用示例:设置进度为50% updateRatingProgress(50)
内容的提问来源于stack exchange,提问作者Scotty
相关产品推荐
相关产品推荐

