Master the design-to-development handoff process — using Figma Dev Mode to extract CSS values, reading red-line annotations, understanding design tokens, and setting up a collaboration workflow that prevents implementation drift.
The design handoff is the moment of highest risk in any product development process. A designer spends weeks carefully crafting the visual and interaction design of a feature. A developer implements it in two days. The finished implementation looks nothing like the design. This pattern — called implementation drift — costs teams days of rework on every feature.
The root cause of implementation drift is almost never negligence. It is a gap in communication: the design file communicates visual intent, but the developer needs technical specification. Figma Dev Mode was built to close this gap, but using it effectively requires understanding what to look for and how to translate what you find into production CSS.
This lesson covers the complete handoff workflow — from reading a design file and extracting CSS values, to setting up a token pipeline that keeps code and design synchronized, to conducting a systematic design QA review that catches drift before it ships.
Figma Dev Mode (accessed via the mode switcher in the top bar) presents a read-only view of the design file optimized for developers. The Inspect panel shows CSS code for any selected element.
Key information available in Dev Mode:
For any element selected:
Figma CSS output examples and corrections:
1/* Figma outputs (Copy CSS button in Inspect panel) */
2/* Figma shadow: x=0, y=4, blur=6, spread=-1, color=#0000000D */
3box-shadow: 0px 4px 6px -1px rgba(0, 0, 0, 0.05);
4/* Convert to modern oklch/hsl for maintainability: */
5box-shadow: 0 4px 6px -1px rgb(0 0 0 / 0.05);
6
7/* Figma letter-spacing: 2% → CSS letter-spacing uses em */
8/* Figma reports percentage of font-size */
9letter-spacing: 0.02em; /* 2% of font-size */
10
11/* Figma line-height: 24 (auto) when font-size is 16 */
12line-height: 1.5; /* always prefer unitless for line-height */
13
14/* Figma opacity: 50% on a layer */
15opacity: 0.5; /* or use rgba color instead of layer opacity */
16
17/* Figma Auto Layout → CSS Flexbox */
18/* direction: Horizontal, padding: 12 16 (top-bottom left-right), gap: 8 */
19display: flex;
20flex-direction: row;
21padding: 0.75rem 1rem; /* 12px 16px */
22gap: 0.5rem; /* 8px */
23
24/* Figma Auto Layout → CSS Grid */
25/* direction: Horizontal, wrap: Wrap, gap: 16 24 */
26display: grid;
27grid-template-columns: repeat(auto-fill, minmax(240px, 1fr));
28gap: 1rem 1.5rem; /* 16px row gap, 24px column gap */Figma component variables (design tokens):
In the Variables panel, Figma stores design token values. The Inspect panel shows which variable is applied to each property:
'Fill: color/brand/primary → var(--color-brand-primary) in CSS'
Red-line annotations are measurements added to design mockups to specify exact dimensions, spacing, and alignment for developers. Before Figma Dev Mode, these were manually drawn in red — hence the name. In modern workflows, Figma's Inspect panel has largely replaced manual red-lines, but understanding annotations remains essential for teams using older workflows or for annotating edge cases.
Common annotation elements:
Translating a typical annotation to CSS:
Annotation reads: 'Card: 16px padding all sides, 12px gap between sections, 8px border-radius, 1px border #E5E7EB, background #FFFFFF, shadow: y=4 blur=6 spread=-1 #00000008'
1/* Direct translation of red-line annotation to CSS */
2.card {
3 padding: 1rem; /* 16px all sides */
4 border-radius: 0.5rem; /* 8px */
5 border: 1px solid #e5e7eb; /* #E5E7EB */
6 background: #ffffff;
7 box-shadow: 0 4px 6px -1px rgb(0 0 0 / 0.03); /* y=4 blur=6 spread=-1 opacity=3.1% */
8 display: flex;
9 flex-direction: column;
10 gap: 0.75rem; /* 12px between sections */
11}
12
13/* State annotation: 'hover: border-color #2563EB, shadow increase' */
14.card:hover {
15 border-color: #2563eb;
16 box-shadow: 0 4px 16px rgb(37 99 235 / 0.12);
17}
18
19/* Focus annotation: '3px offset ring #2563EB 15% opacity' */
20.card:focus-visible {
21 outline: 3px solid #2563eb;
22 outline-offset: 2px;
23 box-shadow: 0 0 0 3px rgb(37 99 235 / 0.15);
24}Content guideline annotation: 'Course title: max 2 lines, truncate with ellipsis'
1.course-title {
2 display: -webkit-box;
3 -webkit-line-clamp: 2; /* max 2 lines */
4 -webkit-box-orient: vertical;
5 overflow: hidden; /* hides overflow */
6 text-overflow: ellipsis; /* ... on truncation */
7 /* Standard property (widely supported): */
8 overflow: hidden;
9 display: -webkit-box;
10 -webkit-box-orient: vertical;
11 line-clamp: 2;
12}Design tokens are the atomic values of a design system: colors, spacing, typography, border-radius, shadow. A token pipeline automatically exports token values from Figma and generates CSS custom properties — eliminating manual copy-paste that causes drift.
Token pipeline tools:
Typical token flow:
tokens.json (output from Tokens Studio):
1{
2 "color": {
3 "brand": {
4 "primary": { "value": "hsl(220, 90%, 56%)", "type": "color" },
5 "hover": { "value": "hsl(220, 90%, 46%)", "type": "color" }
6 },
7 "text": {
8 "primary": { "value": "hsl(220, 30%, 10%)", "type": "color" },
9 "secondary": { "value": "hsl(220, 15%, 40%)", "type": "color" },
10 "muted": { "value": "hsl(220, 10%, 62%)", "type": "color" }
11 }
12 },
13 "spacing": {
14 "2": { "value": "0.5rem", "type": "dimension" },
15 "4": { "value": "1rem", "type": "dimension" },
16 "6": { "value": "1.5rem", "type": "dimension" },
17 "8": { "value": "2rem", "type": "dimension" }
18 },
19 "borderRadius": {
20 "sm": { "value": "0.375rem", "type": "dimension" },
21 "md": { "value": "0.5rem", "type": "dimension" },
22 "lg": { "value": "0.75rem", "type": "dimension" }
23 }
24}Generated variables.css (Style Dictionary output):
1/* Auto-generated by Style Dictionary — do not edit manually */
2:root {
3 --color-brand-primary: hsl(220, 90%, 56%);
4 --color-brand-hover: hsl(220, 90%, 46%);
5 --color-text-primary: hsl(220, 30%, 10%);
6 --color-text-secondary: hsl(220, 15%, 40%);
7 --color-text-muted: hsl(220, 10%, 62%);
8 --spacing-2: 0.5rem;
9 --spacing-4: 1rem;
10 --spacing-6: 1.5rem;
11 --spacing-8: 2rem;
12 --border-radius-sm: 0.375rem;
13 --border-radius-md: 0.5rem;
14 --border-radius-lg: 0.75rem;
15}When a designer changes --color-brand-primary in Figma, the CI pipeline regenerates variables.css and opens a PR with the change — the developer reviews the PR instead of manually hunting for every hardcoded color.
Design QA is the systematic comparison of a completed implementation against the original Figma mockup. It should happen before every PR merge for any UI change. The developer running QA opens both Figma and the browser side-by-side and works through a checklist.
Design QA checklist:
Typography
Spacing
Visual
Layout
States
Common drift sources and fixes:
1/* DRIFT: developer used 500 weight, design specified 600 */
2.label { font-weight: 500; } /* wrong */
3.label { font-weight: 600; } /* correct — check Figma Inspect */
4
5/* DRIFT: developer estimated shadow, design specified precisely */
6.card { box-shadow: 0 2px 4px rgba(0,0,0,0.1); } /* guessed */
7.card { box-shadow: 0 4px 6px -1px rgb(0 0 0 / 0.05), 0 2px 4px -1px rgb(0 0 0 / 0.03); } /* from Figma */
8
9/* DRIFT: border-radius rounded to nearest 4px instead of exact value */
10.card { border-radius: 8px; } /* guessed 8px */
11.card { border-radius: 12px; } /* Figma specified 12px */
12
13/* DRIFT: line-height set to default instead of specified value */
14p { } /* no line-height: uses browser default ~1.2 */
15p { line-height: 1.7; } /* Figma specified 170% */A complete design-handoff walkthrough — from Figma annotation to production CSS — for a course card component, including tokens, states, and QA checklist.
1<!-- FIGMA ANNOTATION (simulated):
2 Course Card Component
3 Width: 320px (flexible)
4 Background: color/surface (#FFFFFF)
5 Border: 1px color/border (#E2E8F0)
6 Border radius: spacing/radius-lg (12px)
7 Shadow: card-shadow (0 1px 3px #0000000A, 0 1px 2px #0000000D)
8 Hover: border color/brand (hsl 220 90% 56%), shadow: 0 4px 16px #2563EB1A
9
10 Thumbnail: ratio 16:9, border-radius top 12px
11
12 Content padding: spacing/6 (24px)
13 Content gap: spacing/4 (16px)
14
15 Badge: font 11px 700 uppercase tracking 0.08em
16 padding: 3px 8px, radius 9999px
17
18 Title: Inter 17px 700, color/text-primary, line-height 1.35, 2-line clamp
19 Meta: Inter 13px 400, color/text-muted
20
21 Button:
22 height: 40px, padding 10px 20px
23 font: 15px 600, width: 100%
24 bg: color/brand, color: white
25 radius: spacing/radius-md (8px)
26 hover: bg color/brand-hover
27-->
28
29<!DOCTYPE html>
30<html lang="en">
31<head>
32 <meta charset="UTF-8">
33 <title>Handoff Demo — Course Card</title>
34 <style>
35 /* Design tokens (generated from tokens.json via Style Dictionary) */
36 :root {
37 --color-surface: #ffffff;
38 --color-border: #e2e8f0;
39 --color-text-primary: hsl(220, 30%, 10%);
40 --color-text-muted: hsl(220, 10%, 62%);
41 --color-brand: hsl(220, 90%, 56%);
42 --color-brand-hover: hsl(220, 90%, 46%);
43 --color-brand-subtle: hsl(220, 100%, 97%);
44 --color-brand-text: hsl(220, 80%, 20%);
45 --color-success-subtle: hsl(142, 72%, 95%);
46 --color-success: hsl(142, 72%, 35%);
47 --radius-md: 0.5rem; /* 8px */
48 --radius-lg: 0.75rem; /* 12px */
49 --space-6: 1.5rem; /* 24px content padding */
50 --space-4: 1rem; /* 16px content gap */
51 --shadow-card: 0 1px 3px rgb(0 0 0 / 0.04), 0 1px 2px rgb(0 0 0 / 0.05);
52 --shadow-card-hover: 0 4px 16px hsl(220 90% 56% / 0.1);
53 }
54 *, *::before, *::after { box-sizing: border-box; }
55 body { margin: 0; background: #f1f5f9; font-family: 'Inter', system-ui, sans-serif;
56 display: flex; justify-content: center; padding: 2rem; }
57
58 /* Course card — exact Figma spec translation */
59 .course-card {
60 width: 320px;
61 background: var(--color-surface);
62 border: 1px solid var(--color-border);
63 border-radius: var(--radius-lg); /* 12px */
64 box-shadow: var(--shadow-card);
65 overflow: hidden;
66 transition: border-color 200ms ease, box-shadow 200ms ease;
67 display: flex;
68 flex-direction: column;
69 }
70 /* Hover state from Figma prototype annotation */
71 .course-card:hover {
72 border-color: var(--color-brand);
73 box-shadow: var(--shadow-card-hover);
74 }
75 /* Thumbnail: 16:9 ratio, top radius = card radius */
76 .course-card-thumbnail {
77 aspect-ratio: 16 / 9;
78 overflow: hidden;
79 position: relative;
80 border-radius: var(--radius-lg) var(--radius-lg) 0 0;
81 background: var(--color-brand-subtle);
82 display: flex;
83 align-items: center;
84 justify-content: center;
85 font-size: 2.5rem;
86 }
87 .course-card-thumbnail img {
88 width: 100%; height: 100%; object-fit: cover;
89 }
90 /* Content area */
91 .course-card-body {
92 padding: var(--space-6); /* 24px content padding */
93 display: flex;
94 flex-direction: column;
95 gap: var(--space-4); /* 16px content gap */
96 flex: 1;
97 }
98 /* Badge row */
99 .badge-row { display: flex; gap: 0.375rem; }
100 .badge {
101 display: inline-flex; align-items: center;
102 /* from annotation: 11px 700 uppercase tracking 0.08em, 3px 8px radius 9999px */
103 font-size: 0.6875rem; font-weight: 700; text-transform: uppercase;
104 letter-spacing: 0.08em; padding: 0.1875rem 0.5rem; border-radius: 9999px;
105 }
106 .badge-beginner { background: var(--color-success-subtle); color: var(--color-success); }
107 .badge-popular { background: var(--color-brand-subtle); color: var(--color-brand-text); }
108 /* Title: 17px 700, text-primary, line-height 1.35, 2-line clamp */
109 .course-title {
110 font-size: 1.0625rem; /* 17px */
111 font-weight: 700;
112 color: var(--color-text-primary);
113 line-height: 1.35;
114 margin: 0;
115 /* 2-line clamp from content annotation */
116 display: -webkit-box;
117 -webkit-line-clamp: 2;
118 -webkit-box-orient: vertical;
119 overflow: hidden;
120 }
121 /* Meta: 13px 400, text-muted */
122 .course-meta {
123 font-size: 0.8125rem; /* 13px */
124 font-weight: 400;
125 color: var(--color-text-muted);
126 margin: 0;
127 }
128 /* Button: height 40px, padding 10px 20px, 15px 600, full width, radius-md */
129 .course-btn {
130 display: block; width: 100%;
131 padding: 0.625rem 1.25rem; /* 10px 20px */
132 height: 2.5rem; /* 40px */
133 background: var(--color-brand);
134 color: white; border: none;
135 border-radius: var(--radius-md); /* 8px */
136 font-size: 0.9375rem; /* 15px */
137 font-weight: 600;
138 font-family: inherit;
139 cursor: pointer;
140 text-align: center;
141 transition: background-color 150ms ease;
142 margin-top: auto; /* pushes to bottom */
143 }
144 .course-btn:hover { background: var(--color-brand-hover); }
145 .course-btn:focus-visible {
146 outline: 2px solid var(--color-brand);
147 outline-offset: 2px;
148 }
149 </style>
150</head>
151<body>
152 <article class="course-card">
153 <div class="course-card-thumbnail" aria-hidden="true">⚛</div>
154 <div class="course-card-body">
155 <div class="badge-row">
156 <span class="badge badge-beginner">Beginner</span>
157 <span class="badge badge-popular">Most Popular</span>
158 </div>
159 <h2 class="course-title">Complete React Developer Course: Hooks, Context, and Advanced Patterns</h2>
160 <p class="course-meta">24 lessons · 8 hours · Certificate included</p>
161 <button class="course-btn" type="button">Enroll free</button>
162 </div>
163 </article>
164</body>
165</html>Every CSS property in this component traces to a specific Figma annotation value. The card's box-shadow is not estimated — it is the exact RGBA values from the Figma shadow effect. The badge's letter-spacing (0.08em) comes from the Figma typography annotation showing 8% tracking. The -webkit-line-clamp: 2 implements the '2-line clamp' content annotation. The button height (2.5rem) and padding (0.625rem 1.25rem) exactly reproduce the Figma specification of 40px height and 10px/20px padding. Design tokens are CSS custom properties generated from tokens.json — changing the brand color in Figma propagates to CSS without manual editing. This is a zero-drift handoff.
This completes the UI/UX Fundamentals module. You now understand the full design process from user research through design handoff. The next module, Figma for Developers, covers the tool you will use for most of your visual design work — from basic navigation through advanced component systems and the token workflow you just learned about.
Your progress is saved in this browser, on this device only.