Chi Señires

I made a responsive Progress Bar component in Figma

When I figured this out initially, I was figuratively slapping myself silly in my head because of how simple the solution was. Just wanted to share this so I remember that sometimes, the simplest solution is the best.

This post has a bunch of screen recording videos embedded with me walking you through some steps via Figma Cursor Chat. The text is a bit small when viewed initially in the preview, so feel free to go fullscreen for any of them!

A bit of a demo

Let me show you first how the finalized component works so you get a better idea of what I mean when I say it’s responsive when you resize it:

So now I know that if I set the component to the 10% variant, the fill is actually 10% and not some arbitrary width. When adjusted to 15%, then it fills up to 15%, and so on.

Getting the component

Screenshot of the Publish Community File modal in Figma showing the preview thumbnail of the Responsive Progress Bar component file by Chi Señires.
Published to Figma Community!

I published the component in a Figma Community File so anyone who needs this specific use case can utilize it: Responsive Progress Bar component

Why I made this

For the longest time, when I had to deal with progress bars in designs I’m working on, I’ve always wanted to make sure the mockup was as close as possible to what it was trying to represent. That would mean, if I were showing a progress bar next to something that said, Step 1 of 4, the progress bar should be 25% filled in and not some arbitrarily adjusted width based on eyeballing it.

It was a random nitpick I kept getting that I wanted to quell for a while. I know at the end of the day, what matters more is making sure whoever you’re communicating the design to understands what the whole thing is trying to represent. Whether the progress bar is set to exactly 25% or just a randomly put together set of elements doesn’t really matter too much compared to how it works when implemented in code.

Like, seeing a progress bar represented in a design mockup? The label says it’s supposed to be 30% full but you’re not sure if the width of the indicator equals what it’s supposed to be compared to its container? That doesn’t really make or break the design, so long as the developer understands how a progress bar is supposed to work or if people reviewing it understand that, ah, yes, that’s just gonna be fixed in the implementation.

Meanwhile, seeing a coded implementation of a progress bar with the label set to 30% and is incrementing upwards but the indicator isn’t growing or shrinking based on the shown value? That’s a bug and that should be fixed. (Ideally…?)

So even while knowing that, I still wanted to make sure the components I use in my designs match what they’re supposed to represent. I don’t really like lying, and not making sure the progress bar width is set to exactly the expected percentage width feels like I’m lying to whoever is looking at the progress bar in the file.

Weird feeling, but okay…

How I did it before

The previous way I did this before was utilizing Auto Layout’s properties. But admittedly, that was a very complicated way of setting up the progress bar component. It was trying too hard to be accurate always, as much as possible.

The indicator in the progress bar was set to Fill the width, and the right padding of the Auto Layout parent Frame would need to be set to this formula: <width of the parent frame> * (1 - <the actual percentage you wanted to show>).1 For example, if I wanted to show a progress bar that’s 500px wide and 20% filled, I would set the right padding to: 500 * (1-0.2). That would equate to 400, which is 80% of 500px, but it’s coming from the right, so it pushes the width of the Indicator layer to effectively the equivalent of 20%, which is 100px.

And if I wanted to adjust the progress bar so it was filled in a very specific percentage—say, 59%—I’d just have to type the equation within the field and it would adjust accordingly. If I wanted to demonstrate how the progress bar was filling up, then I could just click and drag from the right padding icon and set it to the fill I want.

This initially seemed neat and all at the time when I did it, but I recognize that this might be too much to ask for other designer teammates—who just need to get a progress bar in the design, no matter what the fill amount was—to have to go into the Auto Layout settings for this component and adjust it by typing a formula in the Right padding field every time you needed to adjust the fill amount of the progress bar.

It did make the component lightweight in a way though, since it literally was just a rectangle wrapped in a Frame with Auto Layout applied, and you’d only need to adjust the Right padding value to adjust it. But it’s not that intuitive to someone who’s not familiar with Figma’s Auto Layout feature, or maybe someone who didn’t know you can type formulas into the fields to get the specific number you need.

So I knew I had to try and figure out a way to make a responsive progress bar again.

How to set up this new version

The short answer

The short answer is: know your Figma constraints.

The slightly-longer-than-the-short answer is: don’t over-engineer your components! You do not need Auto Layout for everything. You just need to set the horizontal constraints to Scale and you’re done.

The long answer

I’ll do my best to not make this too long as I initially had a very rambly version set up here but chose to scrap it because even I was finding it to be too long.

The initial Progress Bar component I was editing already had some variants set up to represent the different percentages it could be filled, from 0% to 100%. The only real issue was that if I resized the component, only the parent Frame to that indicator layer resized, and not the Indicator itself. It was stuck to the same width as it initially was set up to be.

I first looked up other similar component implementations in Figma Community to see if this has been solved already by someone else. I took a peek at Ant Design components and Lightning Design System Web Components, but the former had the same initial issue as I did, and the latter’s solution wouldn’t work if the Indicator was filled with a gradient since it relied on Auto Layout and toggling the fill of sectioned rectangles that fill up the whole progress bar. It only works for solid-filled progress bars.

I also knew I couldn’t just outright replace the component in our Design System to my initial version because, again, I recognized it would be too complicated to get other designers to use it, plus everyone would’ve had to update the Progress Bar components previously used if ever.

In my previous work, we were using a progress bar to indicate the total amount of credit you had for your account. So I felt like showing a more accurate representation of how much the user had left made more sense then.

Going back to the use case in my current work, the set percentage variants were enough for our setup since we don’t have to be super particular about the fill of the progress bar.

So now I’m trying to update the existing component, but kept scratching my head as to how to set it up.

I had a feeling Constraints did have something to do with it, but for some reason it didn’t occur to me to just try and set the left and right constraints to Scale to get it to work. Initially I kept trying to attach it either to the left only or right only, or both, since I thought that by setting it up as L + R, the left side should always be attached to the left side where it is now—AKA at x=0—and the right side of the indicator would grow and shrink with its parent container.

So when I saw this behavior where the right side would just keep growing, I was stumped for a while because it didn’t make sense to me. I thought that L + R and Scale could be interchangeable, because previous observations got me to think this is how it worked. But I guess there is a reason why it’s different if you set it up as Scale or if you set it up as attached to the left and right sides; the former is how I initially thought L + R would work, and the latter meant Figma would make sure the right side of the Indicator kept its position the same in relation to the right side of the parent Frame.

The first time I figured out Scale was the answer, it was already almost 6pm—meaning I was already working outside work hours, as I normally only worked until 3–4pm—and I think I was at my wit’s end at the time. The relief I felt when I saw it work after setting it up in the correct way was just like a knot was released and I could relax now.2

Parting thoughts

I know what I did was arbitrary or wasn’t really something that would make or break any design I’d be working on. At the end of the day, what matters more in this context is for the components to serve as the designer’s shared language with developers and other people in the company. And sometimes that can be achieved by just manually setting this up instead of the amount of time and effort I put into making this work.

Meme showing devs saying no to do a task which takes 5 minutes, but yes to making a script to do the task which would take 30 minutes.
You know, just like this but put in my context as a designer. 😆 (I was gonna make a meme like this for designers but I realized I’m the only one that would do this… so nevermind hahaha)

But despite being aware of that, the urge was still there in me to “fix” it, or set this up. And now I’ve shared it with my teammates; I don’t know if they’ll care that the component can now be resized and it’ll still communicate the same thing, that it’s filled up to the certain percentage based on the selected variant, but at least now I know that when they use it in their designs, if I see it, I wouldn’t feel the urge to “fix” it anymore. 😆

On my end, I’m also doing my best to learn to let things like this go, especially if it ends up eating more time than my actual work tasks. But for this specific case, I’m happy it only took me an afternoon to figure out 😝 At least I didn’t seem to waste too much time? haha

Footnotes

  1. When I prepped the recording to include in this post, even I got confused with the rule I set up before haha so that goes to show this way could work, but will need some handholding 😆

  2. I’m assuming the average designer doesn’t think like this, this might just be me lol

Webmentions

No mentions yet.

These are webmentions via the IndieWeb and webmention.io. Mention this post from your site:

You can also reach out to me online if you have thoughts to share about anything I’ve posted. Mostly I’m on Threads, Mastodon, or Bluesky.

Back to top ↑