How can I preserve scale of nested icon instances with variants

I’m hoping I can find a resolution to this as I’ve been confused about the product behaviour since variants launched last year.

Essentially, I have icon library for which each are defined as a component. They follow a standard naming scheme (starting with icon/) so that icon instance can easily be swapped using the Swap Instance menu option. They also follow a standard sizing of 24x24 px.

In a common pattern, I then need to create a standardised Button component. I create this component and add an icon instance inside the Button component. Then, to extend this library, I create a new variant of the Button component which is the “small” variant. For this I need to make everything smaller including the icon, so I use the scale tool to reduce the icon instance to 12x12 (which also decreases the line weight). This scaling behaviour is commonly done by browsers when resizing SVGs.

When I create an instance of either the “normal” or “small” button, everything seems fine. However as soon as I want to swap the icon instance in the “small” button instance, the scaling of the icon that is swapped in doesn’t match. It is correctly sized at 12x12 however the line weight is not scaled down as expected.

I have created a step by step reproduction of the issue in this public Figma file, and I include a brief screenshot of the Figma file below for reference.

If anyone can help me with this highly confusing behaviour I’ll be eternally grateful. I simply don’t understand how people can work with icon libraries and the variants feature when scaling of icons isn’t managed consistently by Figma components.

5 Likes

From personal experience, the solution to this problem (not just for Figma), is to outline strokes of icons when they’re part of a library and delivered as an asset (SVG).

It’s good to keep a separate file of the original icons with stroke paths so you have a “source” that can be edited and worked on, but once the icons are ready to be added to a Figma library or exported as SVGs, all strokes should be conveted to outlines. This makes changing the fill color easier not only in Figma but with CSS (for SVGs). And on top of that, you avoid the problem you’re dealing with altogether since you’re only dealing with shapes and fills.

1 Like

Thanks for your response! This seems a little strange to me - I’ve inherited this from previous designers who already had the icons in a separate Figma file as a library. Perhaps I should go investigate that source a little bit more.

I also found this on the forum: (Issue) Keep the scaling of a nested component when swapping it

It seems that the issue of nested instances not retaining their scale is an issue that doesn’t just affect things like icons.

1 Like

Facing the same issue here. Outlining is not a viable option for me. Only work around I have found is detaching. When detaching the component, the correct scale is applied to the nested component.

I have seen the same issue on some of Figma playground.

Check that one about variant. The variant menu for mobile/desktop is buggy. Drag an instance of the menu and the highlight is offset.

I was having a similar issue with nested variants. I have:

Component 2 [ Variant 2.A(Variant 1.A), Variant 2.B(Variant 1.A), … ]

where the variants of component 1 are different sizes and scales.

Replacing Variant 1.A within the master component for 2 scaled properly, but not when I replaced it in component 2.

I was able to resolve this by going to Component 1 and adding auto layout to all the variants. This yielded correct scaling in the instances when the variant was switched out. I don’t know if this will work with variants, and I don’t know why the auto layout I had on the components before combining into variants didn’t carry, but it’s worth a shot.

I think I’m having a similar instance building out a Material Design List Component. I’ve built out 1, 2 and 3 line List Rows which due to their content have different heights. I am wanting to nest them inside of a parent component called List State so that I can have interactive component linkage for hover, selected and dragged states without quadrupling my already huge (288 variants) List Rows variant.

Inside of the variant container for List State, when I swap the instance of List Row, the parent (List State) changes height to accommodate the larger or smaller nested List Row.
Instance resizes

The problem is when I use an instance of List State and swap the nested List Row, it no longer changes height thus making the component useless.
Instance doesn't resize

Just fixed it… Had to set both List State and List Row to Hug Contents inside of the List State Variant. Could’ve sworn I already had tried that :slight_smile: :sweat_smile:

1 Like

I’m having this issue with buttons that include icons. I’ve made three different, and every time I want to swap an icon for the small button the icon doesn’t scale…

I had this problem too. Fixed it by setting the icon component contents to Scale.

1 Like

I tried out the suggested fix, and whilst this works for instances of the icon component, it doesn’t work when for an instance of a Button component.

I set the icon component to scale, then create an instance and place it in the Button component. If I swap it in that component it works. However, if I then create an instance of that Button, and then try to swap the nested icon instance, the scaling is incorrect.

2 Likes

I am having the exact same issue as described by Ben Greenberg (reviving the topic)

Thank you!! :clap: :clap: :clap: This solved my issue

Hey Ben! i’m struggling with exactly the same issue - Read through all these comments here but doesnt seem like it got fixed…did you figure it out somewhere else?

I was able to fix this using these steps:

  1. Select all the individual strokes that make up my icon
  2. Do a union selection to convert them into one single layer/object
  3. Right click or Shift + Cmd + O to outline the strokes
  4. Set the layer to scale within the component frame

After that, any instances of that icon component scaled correctly by changing the stroke width as well.