---
title: "Figma Design-to-Code — Workflow, Best Practices, Pixel-Perfect Positioning"
aliases: [figma-workflow, figma-to-code, figma-pixel-perfect]
tags: [figma, mcp, workflow, pixel-perfect, positioning]
sources:
  - "raw/Structure your Figma file for better code.md"
  - "raw/Write effective prompts to guide the AI.md"
  - "raw/Avoid selecting large, heavy frames.md"
  - "raw/Add custom rules and instructions.md"
  - "daily/2026-05-13.md"
created: 2026-05-13
updated: 2026-05-13
---

# Figma Design-to-Code — Workflow & Best Practices

## The Required Workflow (do not skip steps)

```
1. Parse URL → extract fileKey + nodeId
2. get_design_context(fileKey, nodeId)   ← primary tool, always first
3. get_screenshot(fileKey, nodeId)       ← source of truth for validation
4. [if truncated] get_metadata → identify child nodes → re-call get_design_context per child
5. Download assets (use localhost URLs from MCP directly — do NOT modify)
6. Translate to project conventions (framework, components, tokens, file structure)
7. Validate visually against the screenshot before marking done
```

The Figma MCP output is React + Tailwind — treat it as a *design reference*, not final code. Always adapt to the project's actual stack, components, and naming.

---

## Pixel-Perfect Proportional Positioning

When implementing hero sections or complex layouts from Figma, convert absolute Figma coordinates to **CSS percentages of the containing panel**. This gives Figma-accurate layout that scales to any viewport.

### Scale Factor
Figma frames are typically designed at **1920px**. If the project's lg breakpoint is **1440px** (as in Tailwind v4 Shumiland), the scale factor is:
```
scale = 1440 / 1920 = 0.75
```

### Panel Width Convention
If the right panel in the design is `W px` wide out of a `1920px` frame, set its CSS width as:
```css
width: calc(W / 1920 * 100vw)
/* e.g. 1228/1920 = 64vw */
```

Position the panel **outside** the max-width content container as `position: absolute; right: 0` on the `<section>` — this lets it extend to the viewport edge.

### Convert Absolute Figma Positions to % of Panel

From Figma dev panel, read the node's `x`, `y`, `width`, `height` relative to the panel frame:
```
element.left%  = element.x / panelWidth  (can be negative for bleed)
element.top%   = element.y / panelHeight
element.width% = element.width / panelWidth
```

**Real example — Shumiland DyvoLis hero (Figma node 3-546, 1920px frame):**

| Element | Figma (px) | CSS (% of panel=1228px) |
|---------|-----------|-------------------------|
| Cat left | -247 | -20.1% |
| Cat top | -334 | -20.7% of panel height |
| Cat width | 1558 | 126.9% |
| Orange circle container left | -153 | -12.5% |
| Orange circle container top | 130 | 8.1% |
| Orange circle container size | 2267 | 184.6% |
| Ellipse SVG inside container | 1858 | 82% of container |

Negative percentages allow elements to bleed outside the panel (e.g. a cat that bleeds left). The panel has `overflow: hidden` to clip anything that escapes the section.

### Z-layering rule
Cat renders on top of the orange circle — declare cat *after* circle in DOM order, or use `z-index`.

---

## Prompting Best Practices

### Be specific about framework + file path
```
"Implement using our existing BtnPrimary component from src/components/ui"
"Add to src/components/sections/HeroSection.tsx, not a new file"
"Use Tailwind v4 with lg=1440px breakpoint, not default 1024px"
```

### Avoid large frames
Select **individual components or sections**, not full pages. Large selections cause truncation or incomplete output. If stuck:
1. Reduce selection to a single section
2. Call `get_metadata` first to map the structure
3. Fetch each major child with `get_design_context` separately

### Frame selection tip
Resize the frame in Figma before exporting to verify Auto Layout behaves as expected at different widths.

---

## Structuring Figma Files for Better Code Output

These Figma-side practices improve MCP output quality:

| Practice | Why it helps |
|----------|-------------|
| Use components (not raw frames) for repeated elements | Enables Code Connect reuse |
| Use variables for colors, spacing, radius | MCP maps tokens to CSS vars instead of hardcoded values |
| Semantic layer names (`CardContainer`, not `Frame1268`) | AI understands intent and functionality |
| Auto Layout everywhere | Results in flexbox/grid code, not absolute positioning |
| Use annotations | Communicates behavior (hover states, responsive rules) that visuals can't |

---

## CLAUDE.md Rules for Figma MCP Projects

Add these to `CLAUDE.md` to avoid repeating yourself every session:

```markdown
## Figma MCP Integration Rules

### Required flow
1. Run get_design_context first for the exact node(s)
2. If truncated: run get_metadata → re-fetch child nodes individually
3. Run get_screenshot for visual reference
4. Adapt output to project conventions (not copy-paste React+Tailwind)
5. Validate against screenshot before marking complete

### Assets
- Use localhost URLs from MCP directly — do NOT modify or replace them
- DO NOT import new icon packages — all assets come from Figma payload
- DO NOT create placeholders if a localhost source is provided
```

---

## Common Failure Modes

| Symptom | Cause | Fix |
|---------|-------|-----|
| Response truncated | Frame too large | Use `get_metadata` → fetch children |
| Orange circle invisible | Wrong z-order or opacity | Check DOM order; circle before cat |
| Panel doesn't reach viewport edge | Panel inside max-width container | Move panel outside container to `<section>` |
| Wrong breakpoint behavior | Tailwind v4 cascade: `md:` beats `lg:` alphabetically | Remove conflicting `md:` where `lg:` should dominate |
| Figma MCP auth error after restart | Stale OAuth token | See [[figma-mcp-oauth-reconnect-restart]] |
| Code Connect tool returns permissions error | Not on Org/Enterprise plan | Use CLI instead — see [[figma-code-connect-plan-requirements]] |
