Creating Adaptive Dot Progress Bars with CSS Gradients and SVG
The article shows how to replace numerous HTML elements with a single CSS‑gradient background tile to build a fully responsive progress bar composed of small dots, explains the calculation of tile size using CSS variables, adds current progress with a linear‑gradient overlay, and offers an SVG alternative that can also be applied to custom range sliders.
Minimal Tile Unit
The repeatable unit for the dot pattern is the C shape that spans the container when its ends are connected. Designing a tile that contains a single dot and the surrounding space allows the background to be tiled across the whole bar.
Radial Gradient Tile
A radial gradient that transitions from white to transparent creates the dot:
.progress {
background: radial-gradient(circle at 8px 50%, #fff 2px, transparent 2px) #ccc;
}By default the background size is 100%, so only one dot appears. Define the step size and tile the dots evenly:
.progress {
--total: 10; /* number of steps */
--step: calc((100% - 16px) / (var(--total) - 1));
background-size: var(--step) 100%;
}Changing --total automatically updates the number of dots.
Adaptive SVG Alternative
For developers who find the radial‑gradient syntax cumbersome, an inline SVG can be used as a data‑URI background. The SVG defines a 2 px white circle at the centre:
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
<circle cx="8" cy="8" r="2" fill="white"/>
</svg>After changing the width/height to 100% and removing viewBox, embed the SVG directly in CSS:
.progress {
background: url("data:image/svg+xml,%3Csvg fill='none' xmlns='http://www.w3.org/2000/svg'%3E%3Ccircle cx='8' cy='8' r='2' fill='%23fff'/%3E%3C/svg%3E") #ccc;
background-size: var(--step) 100%;
}Adding Current Progress
The current step is represented by a CSS variable --progress. A linear‑gradient overlay paints the filled portion, while a pseudo‑element marks the active dot.
.progress {
--progress: 3; /* active step */
background: radial-gradient(circle at 8px 50%, #fff 2px, transparent 2px) 0 / var(--step) 100%,
linear-gradient(#FF5E1A, #FF5E1A) 0 / calc((var(--progress) - 1) * var(--step) + 8px) 100% no-repeat #ccc;
}
.progress::after {
content: '';
position: absolute;
width: 16px;
height: 16px;
border: 1px solid #fff;
background-color: #FF5E1A;
left: calc((var(--progress) - 1) * var(--step));
transition: 0.3s;
}Applying to a Custom Range Slider
The same gradient technique can style the track and thumb of an input type="range". Define --total, --step, and --progress on the range element so the slider visually reflects the number of steps.
[type="range"] {
--total: 20;
--progress: 3;
--step: calc((100% - 16px) / (var(--total) - 1));
-webkit-appearance: none;
appearance: none;
width: 300px;
height: 16px;
background: radial-gradient(circle at 8px 8px, #fff 2px, transparent 2px) 0 / var(--step) 100%,
linear-gradient(#FF5E1A, #FF5E1A) 0 / calc((var(--progress) - 1) * var(--step) + 8px) 100% no-repeat #ccc;
}
[type="range"]::-webkit-slider-runnable-track {
height: 100%;
position: relative;
border-radius: 16px;
background: radial-gradient(circle at 8px 8px, #fff 2px, transparent 2px) 0 / var(--step) 100%,
linear-gradient(#FF5E1A, #FF5E1A) 0 / calc((var(--progress) - 1) * var(--step) + 8px) 100% no-repeat #ccc;
}
[type="range"]::-webkit-slider-thumb {
-webkit-appearance: none;
width: 16px;
height: 16px;
border: 1px solid #fff;
background-color: #FF5E1A;
border-radius: 16px;
}Update --progress on input events:
<input type="range" oninput="this.style.setProperty('--progress', this.value);">Conclusion
CSS gradients provide a compact, scalable way to render decorative dot patterns without extra markup. By leveraging CSS variables, the same approach adapts to different counts, shows current progress, and can be reused with SVG data‑URIs or custom range sliders.
Reference: "不一样的SVG!SVG在CSS背景平铺中的应用" – 前端侦探
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
Full-Stack Cultivation Path
Focused on sharing practical tech content about TypeScript, Vue 3, front-end architecture, and source code analysis.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
