Local Variables in Design Systems
One of the most significant changes we received in Figma was the introduction of Local Variables. This feature, long-awaited by many design systems, aims to establish a closer link between design and code libraries.
But what's the difference between styles? Both can be used for design systems and be published. The major advantage lies in the organization and management of the design token structure. With Local Variables, we can now create a global token that serves as the basis for defining other variables at various levels and collections. Change the global token, and all associated variables change accordingly. Moreover, we can create multiple modes, allowing us to define and switch between, for instance, a light and dark theme or different device sizes. Let's explore this step by step.
Tokens
Like major design systems, any custom system needs to define fundamental truths. Depending on the project's size and flexibility requirements, you might define the semantic layer right away (think PrimaryTextColor, for instance), or, as is more common today, establish a primitive layer linked to your semantic layer.
While nearly all systems make use of multi-layering, achieving this was previously challenging and required manual abstraction when transitioning from design to development. While large systems may extend the semantic levels to the extreme, in my experience, it typically takes 10-30 semantic tokens to describe most of the interface. Similar to development, every team should design for what they need, not what they might need or want.
Variable Types
An interesting aspect is the availability of different types of variables. While this might be a bit confusing when viewed globally, as styles have other types, here are the four types of variables and their usages:
Color: Solid fills for color fill, stroke colors, or shadow effects.
Number: For text layers, radius, width/height, padding/gap, shadow and blur, grids, stroke and opacity.
String: Text layers, variant instances.
Boolean: Layer visibility and variant instances with true/false values.
Update: Figma has updated their variables system to now incorporate typography and gradients! Check out this YouTube video for a tutorial on using variables for typography. Regarding gradients: We can now select color variables as stops for gradients. However, color variables are still limited to solid fills.
Collections and Modes
Now, let's dive into layering this entire variables system. Collections allow us to organize in any shape or form we might deem fit for our system. The first use is in separating the primitive layer from the semantic. Still, we might also localize text in different languages or adjust spacings/radius, etc. Why? Because it allows us to add modes per collection. Your "surface-primary" token can now have two values in two modes (or as many modes as you wish to create), while your primary color in the primitive collection (i.e. indigo-600) will always be defined only once.
So where can we use these modes? We can switch modes on:
Layers
Frames
Components and component sets
Sections
Groups
Pages
Objects with variables have their modes set to Auto by default, meaning they take on the mode of their parent container.
Scoping
Scoping a variable allows us to limit where we can use it. A prime example is if we only want to apply our corner radius number variable to the corner radius in our UI or a spacing variable only for width and height and gaps. Another use of scoping could be to hide all your color primitives from being used directly in a UI, enforcing the semantics-only route. Whether such a restriction is useful is probably up to every project itself.
For projects that keep their design system separate and thus in a published library, a variable can also be hidden from publishing, resulting in the same effect. By the way, just as before with components and styles, you can hide a whole collection from being published by preceding the name with a period (.) or underscore (_).
Helpful Links
And there it is! There are certainly more topics surrounding Local Variables, like Prototypes or Code, but I think this is best moved to another blog post. For now, my advice would be to make use of Local Variables, as, despite the beta tag, they are here to stay and will probably only be more expanded in functionality.