UI/UX Design: The Problem With Variants
By: Nick Lawrence
Tags: Ui Ux Design

What are Figma variants?

Variants are essentially different versions of components that you can have in Figma, which are directly related to, and can be referenced from your original component or component instance.

The following is an example:

As you can see, we have a group of variants of the same normal button component to the left, and on the right we have an instance of that normal button component.

I can then take, select a variant property within my right panel, and the component instance on the right will change to match the properties of the associated variant (in this case Variant3 or the blue button from the variant list).

Sounds like a dream come true, right? Not so fast. Let’s take a closer look at this process to see exactly where the issue occurs.

How do variants work?

Let’s start off with a brand new, fresh component that will act as our master for our variants.

Fresh master component for creating variants.

And let’s create two variants for this component: a blue button and a yellow button.

Button variants with blue and yellow buttons, created from master button example component.

Cool! So far, so good, right?

Now, let’s try something interesting. Let’s say we want to add an icon to one of our button variants. After all, buttons with icons are pretty common, and this is something we might want to do in the future.

We have a new instance of our variant button, now let’s try adding our caret (right-facing triangle) icon to it.

Huh, well that’s weird, it looks like our icon isn’t snapping into our auto-layout correctly at all.

Maybe if we try detaching the instance?

Okay…yeah, that worked, but now we don’t have access to our other variants, so that kinda defeats the purpose of even having them…

Let’s see what happens if we try to add the icon to the blue button variant in our variant list directly, maybe that will work!

Awesome! That seems to be working.

But wait, what if we wanted to change something on our default master component, like the type styles, spacing, or something else.

Would the changes cascade down like you’d think they would?

Aaaaannnnnd…no, they don’t.

Which bring us to the trouble with variants.

The problems with variants

So, now that you’ve seen one of the issues with variants, we need to talk about the rest of them, and their implications.

#1. Variant properties do not cascade

This may just be my number one complaint about variants in general: changes in the properties of the master component do not cascade down into the variants themselves.

This can be a HUGE issue when you’re designing at scale, and need changes to cascade, rather than having to go through and deal with it manually.

Which brings us nicely to our next point, making sub-components doesn’t fix the problem either.

#2. Making sub-components doesn’t entirely fix the problem

Now you’d think that you could just make sub-components and it would fix the problem, that is creating an instance of a component, and then making variants off of that one.

The problem is, that doesn’t work either, and I’ll show you:

To clarify, we now have a sub-component, that is referencing our master normal button component, and we are creating variants off of that.

Let’s see what happens:

Now, we can add a stroke, and LOOK AT THAT! It added it to the rest of them too! That’s great, right?

Hang on a second.

Remember our example from earlier?

Yeah, that doesn’t work now.

#3. Variants force you to think imperatively

The problem here now, is that if we want to add an icon to our button, we have to backtrack to our original component and add it there.

We add it here, it adds it to every single variant down the line; if we want to turn it OFF, we have to go through each variant and toggle it off manually.

Cool, turned it off, mission accomplished?

Sort of.

After you’ve done that, if you want too anything else or make mods, you can, but it comes with the same ramifications that we just went through.

This is to say that either:

ALL changes cascade down and THEN must be overridden manually,

You make individual components and sub-instances for each use-case, or

You detach your instances which defeats the entire purpose of having components with linked properties anyway.

This is, as many designers would say, far from ideal. Which brings us to our sweet, sweet workaround.