Skip to content

BlogDesign QA

Design drift: why your live site stops matching Figma

Every site slowly stops matching its design. Where drift comes from, what it quietly costs, and how to catch it before your client does.

DinoFounder of layernote · Jul 7, 2026 · 4 min read

Put any production website next to the Figma file it was built from and count the differences. A font weight here, twelve pixels of padding there, a button color that was updated in the design but never in the code. None of it was decided. It accumulated. That accumulation has a name: design drift.

Drift is worth naming because it is nobody's fault, which means nobody fixes it. A bug has a reporter and an owner. Drift has neither. It is the gap between two artifacts that each keep changing on their own schedule.

Where drift comes from

The handoff loses information. A design file encodes hundreds of decisions: spacing values, weights, line heights, corner radii. A developer rebuilding that from inspection will get most of it right. Most is not all, and the misses are invisible until you put the two side by side.

Browsers add opinions. Default line heights, font rendering, form controls: the same values produce slightly different output than the design canvas, and slightly different output per platform.

Real content arrives. The design had a six-word headline; marketing shipped eleven. The CMS serves a portrait photo into a landscape slot. Layouts bend to survive, and every bend moves the site further from the file.

Quick fixes skip the design. A launch-week bug gets patched straight in code. Reasonable call, but the design file no longer describes the site, and the next feature gets built from a file that lies.

Both sides keep evolving. The designer refreshes a component in Figma; the site keeps the old one. The developer improves a spacing in code; the file keeps the old value. After a year, which one is the source of truth? Neither, and everyone knows it.

What drift actually costs

The visible cost is polish. Users cannot name the inconsistencies, but they read them the way you read a restaurant with sticky menus: something here is not quite cared for.

The bigger costs are internal. Designers who see their work ship at ninety percent stop fighting for the last ten, and quality settles a notch lower each cycle. New pages get built by copying existing pages, so every drifted value becomes the template for the next one. And when the site and the file disagree everywhere, redesigns start from archaeology instead of from the file.

For agencies there is a sharper version: the client holds the design you sold them, opens the site you shipped them, and does the comparison you skipped. That conversation costs more than any QA pass.

How to catch it

The manual version is a design QA pass: design and site side by side, section by section, at more than one viewport. It works, and almost nobody sustains it, because doing it properly takes hours per page and it competes with new work for the same hours.

What makes the pass last is making each finding cheap to report and cheap to fix. Pin it on the exact element of the live page instead of describing it in a message, and hand it to your coding agent over MCP: the agent fixes it in the codebase and marks it resolved with what changed, so the loop from found to fixed does not depend on anyone's spare hours.

One caution: not every difference is a defect. Sometimes the build is better, because the developer fixed something the design never confronted, like a breakpoint the canvas did not cover. A drift check should end with a decision per difference: fix the site, or update the file. Both outcomes close the gap, and closing the gap is the point, because the file you can trust is the one that makes the next project faster.

Drift is not a moral failing and no team prevents it completely. The difference between sites that feel crafted and sites that feel tired is only whether someone measures the gap before the users do.

Read nextSee how layernote goes from a note to a fix
Written by DinoFounder of layernote · @dino_murs on X

More from the blog