TL;DR: We are going to take raw JSON from Figma variables and automatically turn it into working CSS custom properties using Style Dictionary.
The problem
Picture this. You are building a new component. You open Figma to check the design. You click on a button and see it uses a specific blue. You copy the hex code. You paste it into your CSS file.
Then the designer decides that blue is actually a bit too dark. They update it in Figma. But your code still has the old hex value. You do not find out until someone complains that the staging environment looks weird.
This happens all the time. Keeping code in sync with design is a massive headache. Tbh it is usually the worst part of building a UI. You just want to write logic and layout. You do not want to be a human copy machine for hex codes.
The good news is we can fix this. Figma lets you use variables for colours and spacing. We can take those variables as JSON and convert them directly into CSS. No more manual copying.
What you need
You only need a few things to follow along. Make sure you have Node.js installed on your machine. We are going to use a tool called Style Dictionary. It is an amazing open source package. It takes raw design data and formats it for any platform. We will focus on CSS today.
Open your terminal and create a new folder for this project.
mkdir figma-to-css
cd figma-to-css
npm init -y
npm install style-dictionary
Step 1: The raw data
First we need some data to work with. When you export variables from Figma they usually come out as a JSON file. The format often follows the W3C Design Tokens draft specification.
Let us create a fake export file to play with. Create a file called tokens.json in your project folder.
{
"color": {
"primary": {
"value": "#0052CC",
"type": "color"
},
"background": {
"value": "#FFFFFF",
"type": "color"
},
"text": {
"value": "#172B4D",
"type": "color"
}
},
"spacing": {
"small": {
"value": "8px",
"type": "dimension"
},
"medium": {
"value": "16px",
"type": "dimension"
},
"large": {
"value": "24px",
"type": "dimension"
}
}
}
This is a very simple example. Real Figma exports will be much bigger. But the structure is the same. You have categories like colour and spacing. Inside those you have your actual values.
Step 2: Setting up the build script
Now we need to tell Style Dictionary what to do with this JSON file. We need a configuration file. Create a new file called build.js in your folder.
We are going to write a short Node script. This script will read our JSON and output a nice CSS file.
const StyleDictionary = require('style-dictionary');
const config = {
source: ['tokens.json'],
platforms: {
css: {
transformGroup: 'css',
buildPath: 'build/css/',
files: [{
destination: 'variables.css',
format: 'css/variables'
}]
}
}
};
const sd = StyleDictionary.extend(config);
sd.buildAllPlatforms();
Let me explain what is happening here. First we import the library. Then we define our configuration object.
The source array tells it where to find our JSON files. You can have multiple files here.
The platforms object is where the magic happens. We defined a CSS platform. The transformGroup tells Style Dictionary to use its built in rules for CSS. This handles things like converting names to kebab case.
The buildPath is where the final file will be saved. Finally the files array tells it exactly what to name the output file and what format to use.
Step 3: Running the build
We just need to run our script now. Go back to your terminal.
node build.js
You should see a message saying the build was successful. Check your project folder. You will see a new build folder. Inside that is a css folder. And inside that is your variables.css file.
The output
Let us look at what Style Dictionary actually generated. Open the variables.css file.
/**
* Do not edit directly
* Generated on Fri Oct 20 2023
*/
:root {
--color-primary: #0052CC;
--color-background: #FFFFFF;
--color-text: #172B4D;
--spacing-small: 8px;
--spacing-medium: 16px;
--spacing-large: 24px;
}
Look at that. It took our nested JSON and flattened it out. It added the CSS custom property syntax automatically. It even added a comment warning people not to edit the file directly.
You can now import this CSS file into your main project. When you use --color-primary in your styles it will perfectly match the Figma design.
Handling dark mode
You are probably thinking about dark mode now. Most modern apps need it. Figma handles this using variable modes. You might have a light mode and a dark mode in Figma.
When you export that data you usually get two different JSON files. Or you get one big file with different themes inside. Style Dictionary can handle this perfectly. You just create different source files for each theme. Then you output them to separate CSS files or scope them to specific CSS classes.
Here is a quick example of a dark mode JSON file. Let us call it tokens-dark.json.
{
"color": {
"background": {
"value": "#172B4D",
"type": "color"
},
"text": {
"value": "#FFFFFF",
"type": "color"
}
}
}
You can update your build script to output a variables-dark.css file too. Then you just load the right CSS based on the user preference. It makes theming incredibly easy to manage.
Automating the whole thing
So basically this script is great. But you still have to get the JSON out of Figma manually. You have to download it and put it in your folder. That still leaves room for human error. I actually got tired of doing this exact workflow. So I built a plugin called Design System Sync to completely automate it. It connects Figma directly to your GitHub or Bitbucket repo. When a designer changes a variable in Figma the plugin automatically generates a pull request with the updated CSS files. You can check it out at ds-sync.netlify.app or find it directly on the Figma Community. It uses the exact W3C formats we just talked about.
Try setting up Style Dictionary in your next project. It honestly changes how you think about CSS architecture.
Top comments (0)