Appearance
Design
Designs produced in Figma should be built with front-end implementation in mind.
A well-organised, consistent design smooths the transition to front-end development, saving time and reducing friction for both design and development.
Reusable design tokens & components
Use Figma variables (or styles, on older files) for colour, spacing, typography, and radii rather than hard-coded values.
Design tokens give a single source of truth that can be mapped directly to a Tailwind config or CSS custom properties, and they make global changes (e.g. rebranding a primary colour) a one-place edit instead of an asset-by-asset hunt.
- Define tokens before starting high-fidelity screens, not after.
- Use tokens consistently throughout the design.
- Avoid one-off values. If a value is used once and isn't part of the scale, that's often a sign the scale needs adjusting, not that an exception is needed.
Consider layering semantic tokens (e.g. primary, danger, surface) on top of primitive tokens, rather than using primitive tokens directly in designs.
A semantic token references a primitive token (e.g. primary → blue-600) and describes the role a colour plays rather than its raw value. This is what actually makes a rebrand a one-place edit – if screens reference blue-600 directly, changing the brand colour means finding every instance; if they reference primary, it's a single alias change.
- Use semantic tokens in components and screens; reserve primitive tokens for defining the palette itself.
- Cover the common roles up front – e.g.
primary,secondary,danger,success,surface,border– rather than inventing one per screen as new needs arise.
Build screens from a shared set of Figma components rather than duplicating and tweaking layers per screen.
This mirrors how the front end should be built – as reusable components – and surfaces inconsistencies (e.g. three slightly different button paddings) before they reach development.
- Use component variants (e.g. size, state) instead of separate disconnected components for what is conceptually the same element.
- Keep component states (hover, focus, disabled, error) defined in the design rather than left for the developer to infer, particularly for interactive elements.
File organisation
Use auto layout for anything that should reflow, rather than absolute positioning.
Absolute positioning in Figma has no direct equivalent in flow-based CSS. A layout built with auto layout maps naturally onto flexbox/grid and behaves predictably as content changes length.
- Default to auto layout for stacks, rows, and grids of content.
- Set padding, gaps, and resizing behaviour (hug/fill/fixed) deliberately, rather than leaving them at Figma's defaults.
Name components, layers, and pages so teammates can find their way around without asking.
- Name components descriptively, ideally matching (or easily mapped to) the corresponding front-end component name, e.g. a
Cardcomponent in Figma and in code. - Keep a consistent page/frame structure (e.g. one page per feature or flow) so screens are easy to locate.
- Avoid generic layer names left over from Figma defaults (
Frame 42,Group 17) on anything a developer will need to reference.
Spacing
Use a spacing scale based on multiples of 4 (4, 8, 12, 16, 24, 32, 48, 64…) rather than multiples of 5 or 10.
4px
8px
12px
16px
24px
32px
48px
64px
Tailwind's default spacing scale is built on 4px increments, so designs that follow the same scale translate directly to utility classes (e.g. p-4, gap-6) without a developer having to round or approximate.
- Avoid arbitrary values like 5px, 10px, or 15px gaps – they don't map to a Tailwind class and force a developer to either introduce a custom value or fudge the spacing.
- Set up Figma's spacing/grid tools (auto layout gap, padding) to snap to the 4px scale so this happens naturally rather than needing manual correction.
Colours
Name colour tokens using a [hue]-[shade] convention, e.g. blue-500, gray-100, red-700, mirroring Tailwind's default palette structure.
blue-50
blue-200
blue-400
blue-500
blue-600
blue-700
blue-900
This makes it obvious how a design colour maps to an implementation class (bg-blue-500, text-gray-100) and avoids ambiguous names like blue-2 or dark-blue that require a developer to guess which shade is meant.
- Where the project uses a custom palette rather than Tailwind's defaults, keep the same
[hue]-[shade]shape (e.g.brand-500) so the convention still holds. - Keep shade numbering consistent in direction – lower numbers lighter, higher numbers darker – across every hue in the palette.
Typography & vertical rhythm
Use a small, deliberate type scale with a fixed set of font sizes and weights.
- Match font sizes and line heights to values that map cleanly to Tailwind's type scale where practical.
- Avoid mixing multiple near-identical font sizes (e.g. 15px and 16px) across a design; consolidate to one.
Establish a consistent vertical rhythm based on the defined spacing scale.
This makes a big difference to how polished a design feels.
- Base line heights on the spacing scale rather than a fixed ratio of font size, since larger text usually needs a proportionally tighter line height than smaller text.
- Check the rhythm holds when titles wrap across multiple lines.
Accessibility
Check colour contrast and interactive element sizing against WCAG guidelines before finalising a design.
Accessibility issues found after a screen is built are far more expensive to fix than ones caught while defining colour tokens and component states.
- Body text should meet at least a 4.5:1 contrast ratio against its background (3:1 for large text). Check this when defining colour tokens rather than per-screen afterwards, so every combination in the palette is safe to use.
- Give interactive elements (buttons, links, form controls) a minimum tap target of roughly 44×44px, even if the visible element is smaller.
- Don't rely on colour alone to convey meaning – e.g. an error state should also use an icon or text label, not just a red border.
- Define a visible focus state for interactive elements; don't assume the browser default will be used or is sufficient.
States & content
Design against realistic content, not just an idealised example.
Designs that only ever show one polished example tend to break in ways that only surface once a developer wires up real data.
- Test designs against short and long content variants, particularly for user-generated text, lists, and tables.
- Include empty states, especially for lists and tables.
- Consider loading and error states for components that are likely to be interactive or dynamic, such as a product search.
Icons
Use vector icons with a consistent bounding box.
- Ensure icons are vectors that can be exported as an SVG, so they can be scaled and recoloured.
- Use a square bounding box (e.g. 24x24px) shared across the icon set. If more than one size is needed (e.g. 24x24px and 32x32px), keep every icon at a given size aligned to the same box.
- Define and name icons up front, as per design tokens and components.
Responsive behaviour
Design against a defined set of breakpoints, rather than an arbitrary mobile/desktop split.
At minimum, provide a mobile and desktop version of key screens/templates so intended behaviour isn't left to developer interpretation.
Note any elements that should reflow, stack, or hide at smaller breakpoints, particularly for complex layouts like tables or multi-column content.
Consider how any graphical elements should behave at varying breakpoints. Never assume pixel-perfect precision.
Where practical, align breakpoints with Tailwind's defaults, so a developer can implement the design without having to invent custom breakpoint values:
Breakpoint Min width sm640px md768px lg1024px xl1280px 2xl1536px A width of 375px is recommended for mobile.
Handoff
Communicate detail that isn't self-evident from the design.
- Annotate any behaviour that isn't obvious from the static screens, e.g. interactions, animation, or conditional visibility.
- Walk through non-trivial screens with a developer before implementation starts, rather than leaving the design to be interpreted unassisted.
TIP
When in doubt, check with a front-end developer before finalising a design. A five-minute conversation early can save significant rework during implementation.