DEV Community

Emily Carlin for YNAB

Posted on

The Practice: Semantic Colors for Developers

We've already covered the theory behind our semantic color system as well as how it works for designers. This post covers how it works when the rubber hits the road: In code!

We believe that a design system isn’t worth much if it’s only used by designers. So when we started working on this new approach to colors, we knew we wanted to make it simple and usable for developers, too.

So we built a Figma integration that takes all of the color information from our color file and outputs usable code (special thanks/shoutout to Kyle Robinson Young on the YNAB development team, who helped build the integration).

YNAB offers an iOS app, an Android app, and a web app. We rely on our design system to keep things consistent between each platform, so the integration outputs code for each platform.

Alt Text

Each platform has some idiosyncrasies as far as how colors are defined and how light/dark mode switching happens, so we’ll run through each of them.

iOS

For iOS, the integration outputs a color file that is broken into two sections. This is where all of our iOS app's colors are defined.

The first section of the file defines the palette colors. These are private because we never refer to them directly — instead, we refer to semantic colors. This keeps things consistent and guarantees that they look good in light and dark mode.

In the next section of the file, we have our semantic color definitions. These are what actually we use to apply color. Each and every semantic color points at a palette color for light mode and for dark mode.

One of our iOS developers wrote a simple function, that looks at the user’s display mode and determines which color variant to display. That way, things will “just work” between modes. We also built in a safe fallback, in case users aren’t running iOS 13 yet.

We use the description field of the semantic colors from Figma to populate the proper references to the base palette for each semantic color.

Alt Text

Android

For Android, the integration outputs to three color-related files.

First, there’s palette.xml. This is the base color palette where all possible colors are defined.

Next, there’s colors.xml and colors.xml (night). These each have each semantic color listed, with the proper reference to the base palette for each mode — light mode definitions go in palette.xml and dark mode definitions go in colors.xml (night).

When we’re applying colors, we simply refer to colors defined in colors.xml and the right variant renders based on the user’s mode.

Alt Text

Web

We use Stylus for our web app, so we output a palette.styl, colors.styl, and dark-theme.styl file.

As you can probably anticipate from the structure of iOS and Android, palette.styl contains the base palette colors. ‘Colors.styland ‘dark-mode.styl contain CSS variable definitions that reference the proper base palette colors.

So when we are applying colors, we use the CSS variables we define in colors.styl and dark-mode.styl and render the right variant based on the mode the user has selected.

We haven’t released dark mode for the web, so this approach is still experimental, but we’re confident it will work just as well as the system has been working for iOS and Android.

Alt Text

Communication between designers and developers

The fact that we output color definitions directly from Figma means that when a developer looks at a design, they can use the exact same name as the designer and the code will “just work.”

Alt Text

The Figma integration makes it easy and lightweight to keep the system up-to-date; relying on manual updates and communication for a system like this would be a surefire way for it to quickly get out-of-date, messy, and to start to diverge between different platforms.

With this system, we simply run the integration any time colors change in Figma (which is our “source of truth” for all things color). Then developers immediately get access to the latest and greatest colors.

But the technical specificities here are less important than the fact that the philosophy and the language around colors are shared between designers and developers. This system gives us a shared language for talking about colors, and empowers everyone on the team to pick the right color for the job.

Questions? Comments? Get in touch!

That’s all for our series on how we built a semantic color system for designers and developers at YNAB! Feel free to reach out if you have any questions or suggestions. Our hope is that this system can be as useful to other teams as it has been to us!

Top comments (4)

Collapse
 
locochameleon profile image
loco-chameleon

Hi Emily.

First of all, thanks a lot for sharing your insights. This is exactly the same process I am building up. In my opinion this process is inevitable for every Team out there. Automation is the step needed to assure focus on product development, rather then trying to fix everything manually (inconsistent design over all platforms ugh).

I would love to be an early adopter of “semantic color updater” plugin as well as the Figma integration that outputs code. My heart is beating for awesome stuff.

Keep up the great work!

Collapse
 
ericntd profile image
Eric N

Sorry Emily, it's unclear from your post that the script that generates though Android, iOS and Web resource files is provided by Figma out of the box or sth written in house by you?
If it is written by you, can it be open-sourced and shared with us? :D

Collapse
 
gossi profile image
Thomas Gossmann

Hey Emily,

thank you for your series once again. It helped me to develop theemo and ember-theemo. I wrote two articles about it (afaik YNAB also uses ember), so this might be of interest:

Let me know. I am happy to collaborate on this.

gossi

Collapse
 
eforsmarker profile image
Emil Forsmarker • Edited

Hi and thanks for writing this, it helps alot in process :)
I have a question regarding having multiple brands in the same palette.style and each brand having a (primary) or brand color, how whould you name them or handle it?

Thanks // Emil