如何实现双色线性渐变进度条,使末端颜色匹配对应进度占比
Got it, let's sort out this progress bar problem for you. The core issue with your current code is that when you set the progress bar's width to a percentage (like 50%), the linear gradient gets squashed into that narrower element. Instead of showing the first 50% of the full-width gradient, it scales the entire gradient to fit the element's width—so the end of the bar hits the final color immediately, which isn't what you want.
Here are two straightforward solutions to get the exact behavior you're after:
Solution 1: Use clip-path (Most Intuitive)
This method keeps the full gradient on a 100%-width bar, then clips off the unused portion from the right. It's easy to understand and works seamlessly with dynamic progress values.
HTML
<!-- Container for the empty progress bar background --> <div class="progress-container"> <!-- Progress bar with dynamic progress via CSS variable --> <div class="progress-bar" style="--progress: 50%"></div> </div> <div class="progress-container"> <div class="progress-bar" style="--progress: 25%"></div> </div> <div class="progress-container"> <div class="progress-bar" style="--progress: 100%"></div> </div>
CSS
.progress-container { width: 300px; height: 24px; background-color: #e0e0e0; border-radius: 12px; overflow: hidden; margin: 12px 0; } .progress-bar { width: 100%; height: 100%; /* Full linear gradient spanning the entire container width */ background: linear-gradient(to right, #438600, #8fd747); /* Clip the bar to show only the first --progress portion */ clip-path: inset(0 calc(100% - var(--progress)) 0 0); border-radius: 12px; }
How it works:
- The
.progress-baris always 100% width of its container, with the full gradient applied. - The
clip-path: inset(0 calc(100% - var(--progress)) 0 0)rule cuts off everything to the right of the progress percentage. So for 50% progress, it hides the right 50% of the bar, leaving exactly the first half of the full gradient visible.
Solution 2: Use background-size (Alternative Approach)
If you prefer to keep the progress bar's width tied to the progress value, you can stretch the gradient background so that the bar's width aligns with the correct segment of the full gradient.
CSS Adjustment
Replace the .progress-bar CSS from Solution 1 with this:
.progress-bar { height: 100%; width: var(--progress); background: linear-gradient(to right, #438600, #8fd747); /* Stretch the gradient to (100% / progress ratio) width */ background-size: calc(100% / (var(--progress) / 100%)) 100%; background-position: left center; border-radius: 12px; }
How it works:
- For 50% progress,
var(--progress) / 100%equals 0.5, sobackground-sizebecomes200% 100%. This stretches the full gradient to twice the bar's width. - Since the bar is only 50% wide, it shows exactly the first half of the stretched gradient—which matches the first 50% of the original full-width gradient.
Dynamic Updates
Both solutions work great with JavaScript if you need to update progress dynamically. Just set the --progress variable on the .progress-bar element:
// Example: Update progress to 75% const progressBar = document.querySelector('.progress-bar'); progressBar.style.setProperty('--progress', '75%');
内容的提问来源于stack exchange,提问作者Will Sam

