How do you QA pixel-perfect fidelity between Figma and the browser?
You run a structured visual QA pass: capture the Figma frame at each target breakpoint, open the implemented page at the same viewport size, compare them with an overlay or side-by-side technique, log every deviation with severity and a screenshot, fix drift at the source (typography, spacing tokens, image treatment), then get explicit sign-off against a checklist. “Pixel-perfect” does not mean zero anti-aliasing differences — it means no unexplained, visible drift that changes hierarchy, spacing rhythm, or brand presentation.
Most client-reported “it looks wrong” tickets are not random. They cluster into a handful of drift sources: font substitution and rendering, sub-pixel rounding, line-height and wrapping differences, image crops and compression, and breakpoints that do not match the design’s frame widths. Catch those before the client review and your agency’s approval calls get dramatically shorter. Our Figma handoff checklist for developers covers the pre-build setup that prevents half of these issues.
Visual QA methodology (step by step)
Step 1 — Freeze the source of truth
Lock the Figma frame you are comparing against (version, branch, or approved tag). If design keeps moving during QA, you are chasing a ghost. Record frame names, fill/stroke settings, and whether text layers are using the final web font files or Figma’s approximations.
Step 2 — Build the breakpoint matrix
Do not test “mobile and desktop.” Test the widths where layout behavior actually changes:
| Target | Viewport width | Typical Figma frame | What to check |
|---|---|---|---|
| Mobile small | 320–375px | iPhone SE / 14/15 | Word wrapping, tap targets, hero crop, stacked grids |
| Mobile large | 390–430px | iPhone Pro / Android flagships | Multi-column collapse, nav, tables overflow |
| Tablet portrait | 768px | iPad portrait | Breakpoint flips, card grids, sticky elements |
| Tablet landscape | 834–1024px | iPad landscape / small laptop | Mid-tier layouts, spacing scale compression |
| Desktop | 1280–1440px | Design frame default | Full nav, max-width containers, grid gutters |
| Wide | 1920px+ | Optional wide frame | Content max-width, background bleed, oversize type |
If the Figma file only defines 1440 and 375, every intermediate width is a design gap — QA must flag missing states, not silently invent them.
Step 3 — Capture comparable screenshots
- Browser: full-page screenshots at exact viewport widths, device pixel ratio noted (2× vs 1× changes apparent sharpness). Disable browser zoom; use a consistent browser build — capture in the same engine your cross-browser QA process prioritizes.
- Figma: export the frame at 1× with transparent background off; match the viewport width exactly, not “close enough.”
- Normalize: same scroll position (usually top), animations completed, cookie banners and chat widgets dismissed or mocked.
Step 4 — Overlay and compare
Techniques that work in practice:
- 50% opacity overlay — load both images in a tool that can toggle opacity (Photoshop, Figma itself with one image placed over the other, or a browser diff tool). Misaligned text and boxes show as ghosting.
- Side-by-side split — better for judging hierarchy when pixel overlay feels noisy.
- Diff tooling — pixelmatch-style diffs or Percy/Chromatic-style visual regression for repeat runs; still review manually, diffs are noisy with anti-aliasing.
- Measurement mode — in browser DevTools, measure element boxes against Figma’s inspect values (x, y, width, gap, font-size). Numbers end arguments faster than screenshots alone.
Common drift sources and how to classify them
- Font rendering: Figma and browsers hint and rasterize text differently — expect ±1px glyph differences. Real drift = wrong family, wrong weight (400 vs 500), wrong optical size, or missing
@font-faceleading to fallback metrics. Fix at the token/source level, not withtransform: scale. - Sub-pixel positioning: fractional layout values (
width: 33.333%, negative margins) round differently per engine. If visible at normal zoom, snap to integers or use grid/flex that avoids awkward fractions. - Line-height and wrapping: Figma’s auto line-height vs CSS
line-heightunitless ratios disagree more on multi-line headings. One extra wrapped word changes everything below — treat wraps as first-class QA items on hero and section titles. - Images: wrong crop focal point, object-fit, missing aspect-ratio boxes, over-compression, or Figma frame clipping vs CSS
border-radiusintersections. - Spacing scale drift: 20 vs 24px gaps accumulated across a section. Compare against design tokens, not eyeballs — see Figma to WordPress workflow for token-first implementation.
- Breakpoint mismatch: design at 1440, QA at 1280 → false positives. Always match widths first.
- Dynamic content: longer client copy, localization, or CMS-entered strings that wrap differently from placeholder text.
Bug report template with severity
Every visual bug logged with the same fields keeps triage fast:
- Title: [Breakpoint] Component — what is wrong (e.g., “768px — H2 wraps to 3 lines, pushes CTA below fold”)
- Viewport / browser / OS
- Figma reference: frame link + node ID
- Actual vs expected: both screenshots annotated
- Measured values: expected px vs actual px where relevant
- Likely cause: token, font, layout, image, content
- Severity:
| Severity | Definition | Example |
|---|---|---|
| S1 — Blocker | Breaks usability, hides content, or shatters brand identity | Wrong logo proportions, overlapping text, broken nav |
| S2 — Major | Visible drift a client would call out in review | Wrong heading size, wrong brand color, misaligned grid |
| S3 — Minor | Noticeable on close inspection; fix if cheap | 2px gap delta, slight image crop difference |
| S4 — Nit / accepted | Rendering-level differences that cannot be eliminated | Font anti-aliasing, sub-pixel ghosting at 50% overlay |
Sign-off checklist before client review
- Every breakpoint in the matrix captured and compared (not just happy path)
- All S1 and S2 bugs fixed and re-captured; S3 fixed or explicitly deferred with owner
- Typography: families, weights, sizes, line-heights match tokens
- Color: brand + semantic tokens sampled and compared (watch color-profile shifts)
- Spacing: section rhythm and grid gutters match design scale
- Imagery: crops, radius, overlay opacities, alt text present
- Interactive states designed vs built: hover, focus, active, disabled
- Content edge cases: longest headline, empty state, CMS-fed strings
- Motion: reduced-motion path reviewed; entrance states end exactly at Figma resting state
- Cross-browser spot pass complete per the QA process
- One combined “what we accepted” note for anything in S4
Walk the client through the checklist and the S1/S2 burn-down. Reviewing against shared criteria turns subjective taste into managed risk — the same posture used across our white-label Figma-to-WordPress process.
Where automation helps — and where it stops
Visual regression tools (Percy, Chromatic, BackstopJS, Playwright screenshots + diffing) excel at catching unintended change between deploys once a baseline exists. They struggle with: intentional design updates (baselines need refreshing), dynamic content and animations, anti-aliasing noise across OSes, and judging whether a difference “matters.” Automation is a tripwire, not a reviewer. Humans still judge hierarchy, brand feel, and whether a 6px drift is S3 or S2. Pair automated diffs with a manual pass at each milestone and before every client review.
FAQ: pixel-perfect QA
Is “pixel-perfect” actually achievable between Figma and browsers?
Not to zero difference — font rasterization and sub-pixel rendering differ by engine and OS. Achievable and useful: no visible layout, spacing, color, or typography deviations at target breakpoints, with residual rendering noise documented as S4.
How many breakpoints should we QA per page template?
At minimum: the smallest supported width, the primary design width, and every width where the layout changes structure (often 375, 768, 1024, 1440). Add 1920 if content max-width or background behavior differs.
Who owns visual QA — design or development?
Shared. Developers self-check against tokens before handoff; designers own fidelity to intent and sign off on drift classifications. A single QA lead (often the agency PM or senior dev) owns the bug log and severity calls.
Should we fix every overlay difference?
No. Overlay diffs always show anti-aliasing noise. Fix structural drift: position, size, weight, color, wrap. Log rendering-level differences as S4 and move on — chasing them wastes budget and produces fragile hacks.
How does visual QA fit a white-label delivery?
Run it before the agency presents to the end client, with a documented bug log and checklist. The client sees a calm, finished build; your team keeps a clear record of what was checked — the same standard applied across Figma-to-WordPress engagements.
Read next: white-label web development for agencies · pixel-perfect Figma to WordPress development · GSAP motion and page transitions