How to Fix Squished Gradients on Progress Bars with Container Queries
If you’ve ever used a gradient on a progress bar, you might have noticed a strange visual effect. As the progress bar gets smaller, the gradient can get squished and stretched, looking a bit odd. This tutorial shows you how to fix that common problem using a clever trick with container queries. You’ll learn how to make your gradients look great, no matter the size of the progress bar.
What You’ll Learn
This guide will teach you how to use container queries to control the appearance of gradients within progress bars. You’ll discover how to make the gradient behave as if it’s part of the filled portion, rather than just a background that stretches. This technique ensures your progress bars look professional and appealing across all screen sizes.
Prerequisites
- Basic understanding of HTML and CSS.
- Familiarity with styling progress bars or similar elements.
Steps to Fix Gradient Issues
Understand the Problem
The issue arises because a standard progress bar’s width changes. When you apply a linear gradient directly to it, the gradient itself gets stretched or squished along with the bar’s width. Imagine a rubber band with a drawing on it; as you stretch the band, the drawing distorts. This is what happens to your gradient.
Set Up Your HTML
You’ll likely be using the HTML
<progress>element for your progress bar. For this method to work, we need to make this progress element aware of its own size. The transcript mentions using vendor prefixes like-webkit-progress-barand-moz-progress-barto style the progress bar across different browsers. While modern CSS is improving, some older methods might still require these for full compatibility.Example HTML structure:
<progress class="progress-bar" value="70" max="100">70%</progress>Make the Progress Bar a Container
The key to fixing the gradient is to tell the browser that the progress bar itself can act as a container. We do this by applying the
container-typeCSS property. Setting it toinline-sizemakes the progress bar an inline-level container. This allows us to query its size later.Add this CSS to your stylesheet:
.progress-bar { container-type: inline-size; }Expert Note: By setting
container-type, you enable a new set of CSS features called Container Queries. These let you style elements based on the size of their *container*, not just the whole browser window (which is what media queries do).Adjust the Background Size
Now that the progress bar is a container, we can use container query units to control the gradient’s appearance. Instead of letting the gradient fill the entire width of the progress bar as it changes, we’ll set its size relative to the container’s inline size. The container query unit for inline size is
cqi.Apply the following CSS. This example assumes your gradient goes from blue to red. You’ll need to adjust the gradient colors and potentially the
background-sizevalue based on your specific design..progress-bar { /* ... other styles ... */ background-size: 100cqi 100%; /* Adjust gradient colors as needed */ background-image: linear-gradient(to right, blue, red); } /* You might need vendor prefixes for older browser support */ .progress-bar::-webkit-progress-bar { container-type: inline-size; } .progress-bar::-webkit-progress-value { background-image: linear-gradient(to right, blue, red); background-size: 100cqi 100%; } .progress-bar::-moz-progress-bar { background-image: linear-gradient(to right, blue, red); background-size: 100cqi 100%; }Why
100cqi? This tells the background (your gradient) to be 100% of the container’s inline size. Think of it like saying, “Make this background exactly as wide as the progress bar itself.” This ensures the gradient’s proportions stay consistent relative to the bar’s actual width.Observe the Improved Result
With these changes, as the progress bar fills up, the gradient will appear to grow with it. Instead of the gradient itself stretching, you’re effectively revealing more of the gradient as the progress value increases. This gives a much cleaner and more professional look, making the gradient feel like an integrated part of the progress fill.
Tip: You can also use
100vi(viewport inline) which would give a similar result if the progress bar’s width is directly tied to the viewport width. However,100cqiis more robust because it’s tied to the element’s own container size.Add Transitions for Smoothness (Optional)
To make the progress bar’s changes even smoother, you can add CSS transitions to the width or inline-size property. This will animate the filling of the progress bar, making it look less jarring when the value updates.
.progress-bar { /* ... other styles ... */ transition: width 0.3s ease-in-out; }Warning: While transitions can improve the user experience, ensure they don’t slow down your page performance, especially if progress values update very frequently.
Conclusion
Using container-type: inline-size; on your progress bar and then applying the background-size: 100cqi; property to your gradient is a simple yet powerful technique. It effectively solves the problem of squished gradients, ensuring your progress bars always look visually appealing. This method showcases the flexibility of container queries for solving common design challenges.
Source: Neat container query unit trick (YouTube)