Color tokens in Figma are named variables that store color values, allowing you to update one place and change them everywhere. To create them, define your base hex codes, generate harmonized variations, verify contrast ratios, and import them as Figma styles using a structured naming convention. This ensures consistency across your design system and codebase without manual hex-code hunting.
Why Consistent Color Tokens Matter
Color tokens bridge the gap between design decisions and code implementation. Without them, designers and developers often rely on hardcoded hex values, which leads to inconsistencies when updating a brand color. Tokens abstract these values into semantic names like primary or surface, making it easier to maintain visual harmony across light and dark modes. When you use tokens, changing the primary brand color updates every button, link, and background instantly. This reduces technical debt and ensures that accessibility standards are met systematically rather than case-by-case.
Step 1: Define Your Base Color
Start with your primary brand color. This is the anchor for your entire palette. For this guide, we will use #4F46E5, a common indigo shade used in many modern interfaces. You need this hex value to generate variations that maintain hue consistency while adjusting lightness and saturation.
Avoid picking random shades for your secondary colors. Instead, derive them from this base. If you lighten or darken manually in a standard RGB space, the hue often shifts slightly, making the palette look disjointed. Using a perceptual color space like Oklch ensures that when you lighten #4F46E5, it becomes a lighter indigo, not a purple or blue-tinted gray.
Step 2: Generate Harmonized Palettes
Once you have your base hex, generate variations. You need a primary shade, a lighter shade for backgrounds, and a darker shade for text or borders. Using ColorWell, you can input #4F46E5 and select the "Analogous" scheme. This creates colors that sit next to each other on the color wheel, providing subtle contrast without clashing.
Here is the resulting palette generated from #4F46E5:
/* Base Palette from #4F46E5 */
--color-primary: #4F46E5; /* Base Indigo */
--color-primary-light: #818CF8; /* Lighter Indigo */
--color-primary-dark: #4338CA; /* Darker Indigo */
--color-surface: #EEF2FF; /* Very Light Indigo Tint */
--color-text: #1E1B4B; /* Deep Indigo for Text */
These values are calculated to stay within the same hue family. The light variant is suitable for hover states or secondary buttons, while the dark variant works well for active states or headings. The surface color provides a non-white background option that still feels cohesive with the brand color.
Step 3: Verify WCAG Contrast Scores
Accessibility is not optional. You must ensure that text placed on your background colors meets WCAG AA standards. A common mistake is placing white text on a medium-light background. Let’s check our generated palette against white text (#FFFFFF) and dark text (#1E1B4B).
Using the contrast checker in ColorWell, here are the verdicts for our example palette:
| Background Color | Text Color | Contrast Ratio | WCAG AA Status | Usage Recommendation |
|---|---|---|---|---|
| #4F46E5 | #FFFFFF | High | Pass | Buttons, Primary Actions |
| #818CF8 | #FFFFFF | Medium | Check Large Text | Hover States, Badges |
| #EEF2FF | #1E1B4B | High | Pass | Card Backgrounds, Inputs |
| #EEF2FF | #FFFFFF | Low | Fail | Avoid for small text |
Notice that white text on the light surface (#EEF2FF) fails contrast checks for small text. This is why you need a dedicated dark text color (#1E1B4B) for light backgrounds. Always test both light-on-dark and dark-on-light combinations for your primary surface colors. If a pair fails AA, darken the text or lighten the background slightly until it passes.
Step 4: Export to Figma Styles
Manual entry of hex codes into Figma is slow and prone to typos. Instead, export your verified tokens directly. ColorWell provides a "Figma-ready styles" export format. This format is structured so you can copy the entire block and paste it into your Figma Styles panel or a plugin that supports JSON import.
Here is the exact output you would copy for our example palette:
{
"styles": {
"primary": "#4F46E5",
"primary-light": "#818CF8",
"primary-dark": "#4338CA",
"surface": "#EEF2FF",
"text-dark": "#1E1B4B"
}
}
In Figma, go to the Styles panel (right sidebar). Click the + button next to Color Styles. Paste the hex values one by one, matching them to the names above. If you use a plugin that supports JSON import, paste the block above directly. This creates named styles that you can apply to frames, text layers, and shapes instantly.
Best Practices for Naming Tokens
Naming conventions determine how easy your system is to use. Avoid names based on appearance like "Blue" or "Light Blue." These names break if you change the hue to green later. Instead, use semantic names that describe the role of the color.
For example, use primary for the main brand color, surface for backgrounds, and text for foreground elements. This makes the system theme-agnostic. If you switch to a dark mode, surface can change from white to dark gray, but the component logic remains the same.
Keep your hierarchy shallow. Three levels are usually enough:
- Base: The raw hex values (e.g.,
indigo-500). - Semantic: The role-based names (e.g.,
primary,secondary). - Component: Specific overrides if needed (e.g.,
button-hover).
Most teams only need the first two levels. By linking your semantic tokens to your base hex values, you create a flexible system. When you update indigo-500 from #4F46E5 to a slightly brighter shade, every primary button updates automatically. This separation of concerns keeps your design file clean and your codebase synchronized.