Edit the width of nested components using zero-frames as resizers

I learned about this trick from one of my all-time favorite Config talks: Pushing Figma to its Limits, delivered by Figma community wizards: Chudo Loo, Andrei Iancu, Gleb Sabirzyanov, Vitalii Sologub, and Shuaiqi Sun (aka Mr. Biscuit).

If you need to be able to edit the width of a nested instance within another component, you’re going to need a Resizer. Here’s how you make them and put them to work:

Making a resizer:

  1. Create two auto layout frames on the canvas. Height and width do not matter, just make sure there’s some space between them on the canvas.
  2. Name the one on the left “Left endpoint” and name the one on the right “Right endpoint.”
  3. Wrap these endpoint frames in another auto layout frame. Name it “Resizer.”
  4. Remove any padding on the <span class="figma-frame">Resizer</span>, and set the spacing option to “space between” or “auto.”
  5. Set the <span class="figma-frame">Resizer</span>’s height-resizing rule to “fixed” (it was probably on “hug”) and then set the height to 0.0001. This is effectively like entering 0, but Figma may not allow for that value so you need to use a very small decimal.

    NOTE: It’s possible Figma will someday allow for 0px values! Perhaps even by the time you’re reading this blog post. It’s worth checking if entering 0 works. If 0 does work, great! Use that, If it doesn’t, use the decimal.
  6. Select both the nested <span class="figma-frame">Left endpoint</span> and <span class="figma-frame">Right endpoint</span> layers inside of <span class="figma-frame">Resizer</span> and set them to fill vertically. Their height may register as 1px, but that's okay. If they had a fill color, this is a good time to remove it.
  7. With <span class="figma-frame">Left endpoint</span> and <span class="figma-frame">Right endpoint</span> still selected, set their width to 0.0001.
Screenshot of completed Resizer

You've got yourself a Resizer now! All that's left is to get it inside of the component whose width you want to control. You could drag the Resizer you just made into it, or paste in a copy.

Adding your new Resizer to components

Depending on what component you drop your Resizer into, you should expect to encounter some auto layout wrinkles. For example, if you’re putting this in a date picker:

GIF demoing how adding a resizer into a frame using auto layout can cause wrinkles

Fixing these kinds of wrinkles often involves doing some combination of the following:

  • After you’ve added your <span class="figma-frame">Resizer</span> to your component, wrap everything that’s not your <span class="figma-frame">Resizer</span> in its own auto layout frame. I usually name that frame something like “Content” or “Container.”
  • Double check <span class="figma-frame">Content</span>’s resizing settings. Figma may have given you “Fixed” by default, when you really want “Hug” or “Fill.”
  • Double check <span class="figma-frame">Content</span>’s auto layout alignment and the “space between” value are correct too.
  • You likely need to flip the auto layout direction of the entire component. For example, if your <span class="figma-frame">Resizer</span> is meant to control the component’s width (like in my date picker example), the parent probably ought to have a vertical auto layout stacking order. This ensures that <span class="figma-frame">Resizer</span> will sit above (or below, doesn't matter) <span class="figma-frame">Content</span>, and when <span class="figma-frame">Resizer</span>'s width changes, it pushes and pulls on the parent frame (rather than the parent frame and <span class="figma-frame">Content</span>).
  • You likely want 0px for your “space between” value on the parent frame. This ensure’s the presence of the <span class="figma-frame">Resizer</span> won’t effect the spacing in your component.
  • Important! Make sure the outer frame of the component’s (and any parent frames your <span class="figma-frame">Resizer</span> layer is inside of) resizing rule are set to “hug” on the axis you want it to influence!

Once you've re-calibrated all your auto layout settings, you’re done!

Peel off an instance of the component 'suped up with the newly added <span class="figma-frame">Resizer</span>. Instead of grabbing one of the outer edges and stretching it, click through and select the Resizer frame nested within. Since it’s barely visible on the canvas, I’d recommend selecting it using the layers panel. Once selected, go over to the design panel and scrub through values in the “space between” field.

You should see the component grow and shrink, all while maintaining its ↔️ hug resizing setting!

resizer in action.gif
GIF demoing how a resizers in a date picker component allows me to retain a horizontal hug setting while customizing the width

When to use Resizers

Context-dependent widths. Have you ever had a case where you don't want a certain nested instance to collapse all the way down (hugging), or to fill all available space of its parent? In those cases you need to give them a custom fixed width. And that width might need to change depending on the context. By context I mean what components are around it, the page its on, or the part of the flow the user is in. Without a Resizer, making this kind of override is impossible because of Figma doesn't support overriding fixed-width values of nested instances.

An alternate solution is creating a “width” property with variants for each custom width value you need for that component... that may be fine if your component is in a local file, but I would advise against such a property for your component library. It could tank the performance and usability of your component. Resizers, although "hacky", are a much lighter solution.

Whether or not to componentize your Resizers

Up until March 2023, I would’ve set “nope, it’s not worth it” because the only advantages (that I could think of) of having a componentized resizer provides, is the ability to create pre-set widths width values via variants. But adjusting those property values on a nested instance inside of another component used to have no effect on the parent component’s width! Thankfully this appears to have been fixed.

So now my answer is: ...maybe! Here’s some pros and cons to consider (as always, it’s all about what you want to optimize for):

✅ Pros:

  • Having a "pre-set widths" property on your <span class="figma-component">❖ Resizer</span> could reduce cognitive load on designers. It saves a lot of time, clicks, and thinking. This can be especially beneficial if you have a tight spacing system. Rather than memorizing values and manually punching them in to the "space between" input (which I must admit is a very odd, unintuitive input for this use case), they instead select from a list of pre-defined values. And what’s great is if the value they need isn't listed, they aren't prevented from making that override! They can still select the nested <span class="figma-component">⬦ Resizer</span> from the layers panel, and adjust the space between value.
  • With “expose nested instances” you also eliminate the need to go layer spelunking. Another big time saver for designers!

❌ Cons:

  • Variants add to the “weight” of your Resizer instances. It's not a worrisome amount—Resizers are naturally light as feathers—but if you’re extremely sensitive to performance, this is something to be aware of.

What type of component are Resizers and Zero frames?

Sigh. So Resizers don't seem to fit into any of the 7 types of components I’ve written about. Perhaps this means there’s an eighth type... "Hack components"?

Before Figma released absolute positioning, zero frames could be used to “hack” your way to overlapping auto layout elements. To me the word “hack” implies some fragility and risk, which I like for describing these techniques. Zero frames aren’t immune to going bust someday! Figma could decide to force even the smallest of decimal values to round up to a whole 1, which would make this technique impossible to use (and potentially break any existing zero frames you have in place).

Hack components often contribute to ◈ interface reps to help bridge gaps where Figma isn’t quite mapping to the realities of HTML and CSS. I'd liken using Hack components to taping a timer to a microwave that (for some reason) doesn't come with a built in timer. Figma doesn't provide us with minimum and maximum width controls, but that doesn't mean we can't MacGyver our own!

What are the ways you use zero frames in your component libraries and UI work? @ me on twitter or send me a note in the Figma community forum! I'd love to hear about your solutions.