Building a Design System in Figma
A quick-start guide, with Auto layout and Variants
Apart from being one of the most talked about topic in the design field, the rising need for design systems could be attributed to the following goals:
- Provide consistent user experiences
- Eliminate repetitive design work
- Design at scale in an iterative manner
- Improve designer-developer handoffs
Recently, Nielsen Norman Group published an article about the pros and cons of implementing a design system. Of all the points raised, this is what resonated with me the most:
Teams can continue to use the same elements over and over, reducing the need to reinvent the wheel and thus risking unintended inconsistency.
— Therese Fessenden (NN/g)
I experienced a design inconsistency problem while working with an existing color palette. I was trying to find the “right” shade of green for a new button, and this color was supposed to work with the existing palette. I spent a whole afternoon trying out different shades of green and eventually ended up with a blue. This wasn’t sustainable for a start-up that was trying to deliver a feature as fast as possible. In order to avoid this situation, I decided to create a design system for colors when I started working on another project called Goody app.
I’ve been working on a website for a start-up digital consultancy. Let me share how I have been building a design system in Figma. Auto layout and variants were applied to the most recent iterations.
Exploration
Wireframes
After creating a set of wireframes, I got an overview of the pages that I need to work on and the elements that I need to include.
- Home Page
- Services
- Contact Us
- About Us
- Our Work
- Sitemap
Style Guide:
Color Palette
When you create a new team in Figma, it comes with an existing design system project, and inside is a default file with ‘Color Styles’. This is a great place to start exploring and tinkering with an actual design system, and it’s quite fun! However, when trying to work with an existing color palette, it’s good to start in a spreadsheet before implementing the color palette in Figma.
In this case, I started with a primary and secondary color, I generated a color palette using Material Design Color system tool to provide colors that meet accessibility standards. I transferred the set of HEX values into a spreadsheet, then manually checked the contrast ratio between background and foreground by using WebAIM’s contrast checker tool. From here, I was able to determine which color are suitable to use against white or black texts.
When comparing contrast ratios, I found that the numerical results cannot be the only deciding factor. Sometimes, checking visually made more sense than relying on numbers.
For starters, the contrast ratio has to be at least 3:1 for large texts and 4.5:1 for normal texts to pass WCAG 2.0 AA level. Let’s take an example, Purple 400 / 8057ff has a contrast ratio of 4.72:1 with black text and 4.44:1 when compared with white text. By testing it visually, it is more readable as a background color for white text. Hence, I decided to classify Purple 400 / 8057ff to be used with light-colored texts such as white.
Before going implementing the palette in Figma, I was inspired by an article that showed how to quickly set up a color system in Figma. After settling down with a naming convention, I was able to generate the color chip labels using a plugin called: Smart Text. By selecting ‘Fill Color’ and the ‘Layer Name’, it generated the corresponding HEX values and the corresponding naming conventions.
To generate these as Colors Styles in this Figma file, I used this plugin: Chroma Color. Under ‘Assets’, I published these Color Styles so that they could be used across the whole project. I went through a process of adding and editing color chips as I worked through the style guide. The plugins made it easier to edit and generate new names for each color chip, especially in batches.
Typography
By the time I was exploring type sizes and weights, I applied these color styles to backgrounds and texts. There were several iterations using Helvetica, I recently updated it by applying Figma Variants.
One dilemma was to either combine all the types into one set of variants or to categorize them. Combining all of these types will show everything in one list — this seemed to offer flexibility. On the other hand, categorizing would literally provide a “system” with some constraints. For example, all types under Headers would be found under Headers, and not in Subheaders, nor in Texts.
Arguably, you can select any type when designing and interchange the Variants as needed. In this project, the mentioned constraints were implemented to give a sense of structure and organization.
The typography was classified into 3 main categories:
- Header (Header Light Mode, Header Dark Mode)
- Subheader (Subheader Light Mode, Subheader Dark Mode)
- Text (Text Light Mode, Text Dark Mode)
Naming convention: Variant Name/Type/State
Example: Subheaders Light Mode/Subheader 1 16px/Active
Components:
List of Atomic Components
I initially grouped and identified the main components as the following:
- CTA (Primary Buttons, Secondary Buttons, Text links Navigation, Text links Defaut, Text links Highlighted)
- Form fields
- Alerts
- Icons
As I went through iterations, I realized that it’s hard to group buttons and text links into one Variant based on how they are used. For example, the most critical property to be shown for the text links are the text sizes. With buttons, the focus is more on the sizes of the buttons, and if it had an icon or not.
Hence, I decided to break down the ‘CTA’ components into ‘Buttons’ and ‘Links’. ‘Text links Navigation’ and ‘Text links Default’ turned out to be the same thing with similar behavior, only the text size differed.
Second iteration:
- Buttons
- Links
- Form fields
- Tooltips
- Alerts
- Icons
Buttons:
Variant property setting: Variant Name/Type/Format/State/Size
Example: Buttons/Primary/No-icon/Active/Small
Links:
Variant property setting: Variant Name/Type/Format/State/Size
Example: Links/Secondary Link 16px/Highlighted/Active/Small
Form fields:
For the Form fields, I focused on the states. I identified 2 critical properties:
- Empty Format
- Active Format
I then used Variants to further categorize the other components:
Variant property setting: Variant Name/Type/Format/State
Example: Form Field/Phone Number/Empty/Error
Tooltips:
I decided to create another set of Variants for the Tooltips to better manage and incorporate them to other components in the design system.
Variant property setting: Variant Name/Type/State
Example: Tooltip/Light/Active
Alerts:
At first, I combined all Alert components. Although they are all alerts, the ‘Alert Messages’ did not function the same way as the ‘Alert Headlines’. So I regrouped based on their how they are used. Alert messages are in-line texts that could be found in the Form fields, while Alert banners could be found on top of a user screen.
Variant property setting: Variant Name/Type/State
Examples:
- Alert Messages/Alert 3 20px/Active
- Alert Banners/Alert 1 14px/No Button
Icons
I used open-source icons from feathericons.com.
Complex Components
I applied Auto layout to the simpler components before applying it to more complex ones, termed as “Organisms” based on Brad Frost’s Atomic Design approach.
By using aspect ratio tools from Vitalii and Abel Hancock, a Card or a Dialog from this design system could be resized without the need to constantly resize the attached image.
List of Organism Components
- Navigation
- Cards
- Dialogs
Navigation:
Variant property setting: Variant Name/Type/Format
Example: Navigation/Horizontal/Expanded
Cards:
Variant property setting: Variant Name/Type/State/Size
Example: Card/Horizontal/Active/Large
Dialogs:
Variant property setting: Variant Name/Format/Size
Example: Dialogs/Form/Small
Design Codes
The CSS codes are automatically generated under ‘Inspect’ tab in Figma as you design. If I’m not mistaken, these Inspect codes are only editable to owners or contributors. Here’s a peek at how codes are presented in Figma for a button:
From here, I visited w3schools.com to get a CSS Button html code, I retained the 3rd button from the list and retrofitted it to the button design:
Code: <button class=“button”>Send Message</button>
I edited and explored until I recreated this button in an html file. I realized that it’s not an instant handoff, where anyone could just literally select a button and copy paste the codes in one go (To coders: Correct me if I am wrong). It took me awhile to discover that I had to select several frames to get the codes that needed to be combined and formatted to work.
For example, if I only select a button (Primary/No-icon/Active/Small), the codes under ‘Text 3’ will not be shown until I further click and select ‘Text 3’.
Here’s how it looks like in html, including the codes under ‘Text 3’:
Learnings
Thinking back, I spent a considerable amount of time picking a naming convention for each of the components, and it initially felt like it slowed me down. However, I found that naming and grouping is one of the most important things to decide on before working on the visual elements. By sticking with the naming conventions, awkward names were prevented, it also became apparent to me which components were still missing.
I keep a list of the naming conventions in an Excel sheet, it may appear like a redundant work, but it was helpful when I was cross-checking the consistency of the names. One example is with the Form fields, I used both ‘Phone’ and ‘Phone Number’ in Figma, where in fact they referred to the same element. This is a perfect example of how an error could easily cause inconsistencies and confusion to design system users.
Moving forward, I’m still exploring if I need to use design system documentation tools like zeroheight, given that my current coding skills are limited.
It did took quite some time for me to explore and understand how aspect ratio tools work in Figma. For this matter, Material Design and Atlassian were also some great sources of inspiration.
Figma Auto layout and Variants are customizable in a sense that you can create constraints and flexibility as needed. It has enabled me to weigh in different pros and cons of my design decisions. But more importantly, it has helped me confront if those decisions would be sustainable.
Reflection about design systems
Kick-starting a design system empowered me early on to create different ways of designing. It has allowed me to fix unforeseen issues like a missing component state/format. This would reduce unnecessary workload and even panic in a team.
Therese Fessenden from Nielsen Norman Group writes,
A design system is there to act as a guide for a team, it shouldn’t be followed without question. It should also continually evolve together with the product involved.
With all the hype around design systems, it’s easy to lose track as to why or why we do not need to build one. It’s important to consider that building a design system requires investing time and effort.
Pascal Barry shares how design systems are a waste of time, it is also a single point of failure if it causes an error across all interfaces, and since it’s harder to debug than to deploy, the only solution is for developers to invest more effort in testing and maintaining it. He also argues that designers should focus on more important problems:
Users don’t care if every border-radius on your buttons is the same. They will, on the other hand, quickly ditch your product if you’ve failed to resolve core interaction problems.
Interestingly, Yesenia Perez-Cruz from Shopify writes:
It would be interesting to further find out how this design system project could be improved. Also, I have yet to write about the rarely discussed hurdles that arise from design systems, especially when working in a team, stay tuned.
You can view the design system contents here.
Thanks for reading! Feel free to comment or say hi 💗