The build comes back and the spacing is off, the button does something odd on hover, and a long product name wraps into three lines and shoves the price off screen. It is tempting to read that as carelessness. It almost never is: the developer built exactly what was handed over, and what was handed over described one screen, at one width, with one set of content, in one state.
Here is the core of it: a design file is a snapshot, and code is a system. A good handoff closes that gap by shipping the rules alongside the pictures — how things scale, what every state looks like, what happens when the content misbehaves — and by treating handoff as a conversation that starts early and continues after the files are sent, not a one-way delivery at the end. Everything below is how to do that without producing a hundred-page spec nobody reads.
Why handoffs go wrong
Three failure modes account for most of it.
The file answers only the happy path. Designers naturally compose the ideal screen: perfect-length headline, a product image that exists, four items in the list. The developer then has to make judgement calls about the empty list, the missing image, the twelve-word headline, and the error message. Those calls get made either way. The only question is whether the designer or the developer makes them.
Values are invisible. A layout that reads as "obviously 24 pixels apart" may be 22 in one place and 26 in another because it was nudged by eye. Developers write one number into a stylesheet, so inconsistency that is invisible in a static comp becomes a decision — or a guess — in code.
Handoff is treated as an event. Files go over the wall at the end, with the estimate already committed, so a component that needs a week has been priced as a day. Bringing the developer in during the design phase costs an hour and saves days — they will flag which patterns are cheap, which are expensive, and which fight the framework you already use.
Design in a system before you hand anything over
The most effective thing you can do for a handoff happens weeks before it, while you are still designing.
Use scales, not arbitrary numbers. Pick a spacing scale (4, 8, 12, 16, 24, 32, 48 works for most interfaces) and stay on it. Do the same for type sizes and border radii. Snapping to a scale is what lets a developer write a handful of reusable values instead of transcribing dozens of one-offs — and it is why the built version stops drifting from the design a few screens in.
Name your colours by role, not by hue. surface, text-primary, text-muted, border, danger survive a rebrand and translate directly into code variables. Blue 2 does not tell anyone where it is allowed to be used.
Make components real components. A button that exists as one reusable component with variants is one thing to build. The same button copy-pasted and tweaked eleven times looks like eleven buttons, and someone has to work out which differences were intentional.
Design with real content. Pull actual product names, actual copy, actual data lengths. Placeholder text hides almost every layout problem you would otherwise discover during QA.
Systematic design is not bureaucracy — it is the difference between handing over rules and handing over pixels to be reverse-engineered.
What a complete handoff actually contains
The screens are the easy part. These are the things developers routinely have to ask for.
Every state, not just the default
For each interactive element, show or describe: default, hover, focus (a visible focus ring — keyboard users need it), active, disabled, loading, error, and success. For each view or container: empty, loading, error, and "too much content".
Empty states are the most-skipped and most-visible omission. Something has to render when there are zero results, and if you did not design it, someone else will.
Responsive behaviour, described as rules
Static comps at two widths do not say what happens between them. Specify:
- Which elements are fixed and which are fluid, and any minimum and maximum widths.
- Where the layout genuinely changes — a three-column grid becoming one column is a decision, not an interpolation.
- How the navigation behaves at narrow widths.
- What text does when it overflows: wrap, truncate with an ellipsis, or clamp to two lines.
- Whether images crop, scale, or letterbox, and from which anchor point.
A sentence like "cards stay at least 280px wide and reflow to one column below 720px" saves an entire round of review.
Content edge cases
Name the limits: the longest name the layout must survive, what appears when an avatar or thumbnail is missing, how a list behaves at one item and at two hundred, and whether the interface will be translated — many languages run longer than English, and fixed-width buttons break first.
Spacing, type, and assets
Provide the scales rather than annotating every gap. Give font families, weights, sizes, line heights, and letter spacing as a small type ramp. Export logos and icons as SVG, photography as raster at the densities you support, and name files predictably — icon-cart.svg beats Group 47 copy 3.svg.
Interaction and motion
If something animates, say what triggers it, roughly how long it takes, and what easing it uses — "panel slides in from the right, around 200ms, ease-out" is enough. Also say what shows while waiting on a slow connection: spinner, skeleton, or optimistic update.
Accessibility intent
Note the reading and focus order where it differs from visual order, alt text for meaningful images, labels for icon-only buttons, and minimum touch target sizes. These are trivially cheap to specify and expensive to retrofit.
Annotate what the file cannot show
The goal is not more documentation; it is less guessing. Skip anything the developer can read directly from the file — modern design tools expose spacing, colour, and type values on inspection. Annotate the invisible instead:
- Behaviour and conditional logic ("this only appears for signed-in users").
- Anything that deviates from the system, and why.
- Links between screens: what this button does and where it goes.
- Data sources: what is real, what is dynamic, what is placeholder.
- Priorities: what must ship exactly as drawn versus what can flex.
Keep annotations next to the thing they describe. A separate spec document drifts out of date the moment the design changes, and a stale spec is worse than no spec because someone will trust it.
Run the handoff as a conversation
Send the files, then spend twenty or thirty minutes walking through them live: the goal of the feature, a click-through of the main flow, then the states and edge cases, then the parts you are unsure about. Say which decisions are locked and which are open — developers often know a cheaper way to reach the same outcome, and they will only offer it if they know it is welcome.
Then stop talking and let them ask questions. The questions are the real output of the meeting; each one marks a gap, and writing the answers back into the file is what stops that gap recurring. The same framing applies earlier in the process — if reviews are where your projects lose time, the mechanics of running a design review that ends in a decision are worth fixing first, because unresolved review comments become handoff ambiguity.
Afterwards, keep one channel for questions rather than a mix of chat, email, and file comments. Answer in the shared thread so the second person to wonder does not have to ask again.
Handle changes without breaking trust
Designs change after handoff. That is normal; what breaks projects is silent change. Once a build has started, treat the handed-off version as a baseline: update the file, mark what changed, tell the developer directly, and be honest about whether it is a fix, a refinement, or new scope. A short change log — date, screen, what changed, why — prevents someone building from a version that no longer exists. Version your files so "the latest one" is never ambiguous.
Common handoff mistakes
- Only the desktop happy path — no empty, loading, or error states, and no rule for the widths between breakpoints.
- Off-scale values everywhere — nudged-by-eye spacing makes the developer invent consistency you never committed to.
- Placeholder content, which hides the layout failures that then show up in production.
- Over-annotating — labelling every margin buries the three notes that mattered.
- A spec document separate from the design. It goes stale, and someone builds from the stale version.
- Handing off with no conversation. No questions means no gaps found — until QA finds them.
- Silent revisions, which destroy trust faster than any single bug.
FAQ
What should be included in a design handoff?
Final screens, every interactive and container state, responsive rules with breakpoints and min/max widths, spacing and type scales, colour tokens named by role, exported assets in the right formats, interaction and motion notes, content edge cases, and accessibility intent. Anything that cannot be read directly from the file should be annotated next to the element it concerns.
How detailed should design specs for developers be?
Detailed about rules, brief about pixels. Developers can inspect exact values; what they cannot inspect is behaviour, conditions, priorities, and what happens outside the state you drew. If a note only restates something visible in the file, cut it.
When should the handoff conversation start?
Well before the files are finished. Involving a developer during design — even for a short look at early wireframes — surfaces technical constraints and expensive patterns while changing them is still cheap. Handoff at the end should confirm details, not introduce the whole feature.
Who is responsible when the build does not match the design?
Usually the process rather than a person. If the design never specified the state that came out wrong, that is a handoff gap; if it specified it clearly and the build ignored it, that is an implementation gap. Check the file before assigning blame — the first kind is far more common, and faster to fix.
How do I handle design changes after handoff has already happened?
Treat the handed-off version as a baseline. Update the source file, highlight what changed, notify the developer directly rather than relying on them noticing, and label the change as a fix, a refinement, or new scope so its cost is visible. Keep a short change log so anyone can see which version is current.
Next step
Pick one screen you are about to hand over and list what it does not currently show: the empty state, the error, the focus ring, the long name, the narrow width. That list is your handoff gap, and closing it costs far less than the rebuild it prevents. And if you are assembling the brand assets those screens depend on — logos, palettes, and a consistent social kit — build your brand kit with MyDesign Tool at https://mydesign-tool.com.