Skip to content
Proofel

How our simulation works, and where it can be wrong

There are two ways to answer “what will this email look like in Outlook?”. You can render it on a real machine running real Outlook and photograph the result, which is what Litmus and Email on Acid do. Or you can model what that client does to an email and apply it deterministically, which is what we do. Both are legitimate. They fail in completely different places, and you should know which one you are holding.

A screenshot is the ground truth for one machine at one moment. Its weakness is that it is a bitmap: by the time the client has repainted your email, the authored colours and the CSS are gone. A PNG cannot tell you that the caption in your footer resolves to 4.19:1 once Gmail repaints the panel behind it, because the concept of “the colour you wrote” no longer exists in the file. It cannot tell you which declaration Outlook dropped — only that the corners came out square. And it cannot show you the combinations: dark mode with images blocked at a 320px width is a real state real subscribers are in, and a screenshot service would need to photograph it as its own separate test.

A simulation keeps the model end to end. We transform your HTML — invert its colours in CIELAB space with a per-client model, strip the declarations a given engine does not support, block the remote images — and then render the transformed document in a real browser. Which means every intermediate state is inspectable: we can mount the dark DOM and measure contrast inside it, point a finding at line 214 of your CSS, and compose lenses on top of each other. The cost is that we are describing a client rather than being one, so where a client’s behaviour is undocumented or its layout engine is genuinely alien, we are approximating. That is the trade, stated plainly.

What each engine actually does

Six engines, all deterministic, all running in your browser.

The render itself

Your HTML is sanitized with DOMPurify and mounted in a sandboxed iframe with scripts disabled. From there it is a real browser laying out real CSS — the same engine (Blink) that renders Gmail on the web, Outlook.com, Yahoo Mail and every Android mail app. Nothing about the layout is approximated, because nothing needs to be.

The 20 client lenses

A rules engine, not a screenshot. Each of the 20 client/browser/OS combinations is mapped to the engine that actually renders it — Blink, WebKit, Gecko or Word — and applies only transforms traceable to a documented limitation of that engine: strip border-radius and box-shadow for the Word engine, disable @media blocks for the Gmail mobile apps, rewrite class names the way Outlook.com does. Every transform produces a plain-English note saying what changed and why.

Dark mode

A transform of your HTML, not a filter over a picture. Colours are converted to CIELAB, their lightness inverted around a per-client model, then converted back — which preserves hue while flipping luminance, the way Gmail and Outlook actually repaint. Apple Mail is modelled differently because it honours the dark styles you author. Images are never inverted, exactly as no real client inverts them.

Contrast measurement

Because dark mode produces a DOM rather than a bitmap, we can mount the inverted document and measure it. Contrast comes from getComputedStyle on the live frame, so it resolves inheritance, alpha compositing and legacy bgcolor hints — then the same measurement runs again inside the dark render, which is what surfaces "passes in light, fails in Gmail dark".

Inbox row truncation

Real glyph advance widths from the canvas text API, in each client’s own font stack at its own size and weight, wrapped word by word and clipped at the pixel — the same two-stage behaviour as a line clamp. The tool never returns a character count, because clients do not count characters.

Per-declaration support verdicts

Your CSS is parsed with css-tree into individual declarations, and each one is looked up in the caniemail.com support dataset — so a finding points at a line of your CSS and names the clients that will drop it, rather than showing you a broken screenshot and leaving you to guess which rule caused it.

Three things this catches that a screenshot cannot

All three come from the same property: the email stays a document with colours and CSS, right through the transform.

  1. 1

    Contrast inside the inversion

    Because dark mode is a transform of your DOM rather than a photo, the inverted document can be mounted and measured. A text style that clears WCAG AA as authored and fails at 2.6:1 after Gmail repaints the panel behind it is a finding no pixel-diff product can produce — the numbers it would need stopped existing at the moment of capture.

  2. 2

    Per-declaration verdicts

    Your CSS is parsed into individual declarations and each is checked against the caniemail dataset, so a finding says "this declaration, on this line, is dropped by these clients". A screenshot shows you the symptom; this points at the cause, which is the difference between knowing something is broken and knowing what to change.

  3. 3

    Combinatorial states

    Dark mode, blocked images, a 320px width and a client lens compose, because each one is a transform rather than a separate photo shoot. The state grid renders the combinations at once — and blocked images in dark mode is precisely the pairing that catches a white logo on a white box in an otherwise dark email.

What this cannot do

If a tool never tells you its limits, that is not confidence — it is a sales page.

Pixel-exact Outlook layout

Classic Outlook for Windows lays out on Microsoft Word’s HTML engine, which has its own table model, its own handling of margins and widths, and DPI scaling behaviour that varies with the user’s display settings. We can tell you which of your CSS it will drop and lint the constructs it mishandles. We cannot promise the result is positioned to the pixel the way a screenshot from that machine would be. For a campaign where Outlook is a large share of your list, test on a real Windows Outlook.

Your specific device, fonts and zoom

Canvas measurement resolves the first font actually available on the machine running the tool, so a Mac without Segoe UI falls further down a Windows client’s stack and shifts the numbers slightly. Inbox pane widths are elastic too — a maximised 27-inch Gmail window shows much more than a split-pane Outlook. Each spec models a common, defensible default and records what it was calibrated against; it is not a measurement of your reader’s window.

Per-account and rolling client differences

Gmail renders differently depending on the account type (a consumer address, a Workspace address, an address hosted at Gmail via IMAP), the mobile app version, and whatever they shipped this month. Where a behaviour genuinely is not documented, the lens says it is unverified rather than inventing a transform. A rules engine is always slightly behind reality; a screenshot farm is a snapshot of one moment in it.

Whether a filter will deliver your message

Nothing on this site can tell you that. SpamAssassin is one widely-deployed open-source filter, not Gmail, Outlook.com or Yahoo, all of which use proprietary systems fed by your reputation and your recipients’ behaviour. The DNS check tells you whether your domain is set up to be trusted; it cannot tell you what a given provider thinks of you today.

Blocklist status

Deliberately not checked. A DNSBL answer is only truthful from the resolver that will deliver the mail, and the major lists refuse queries from public resolvers — where a refusal is indistinguishable from "not listed". We report the gap as a finding instead of showing a green tick we cannot stand behind.

Anything about the copy being good

The subject-line tool flags shouting, punctuation pile-ups, unrendered merge tags and value buried at the end of a sentence. It has no opinion on whether the offer is any good, and the promotional-term list is a tone flag rather than a score — no mainstream filter keys off a subject keyword in isolation, and we will not pretend otherwise for a nicer-looking gauge.

How we handle not knowing

Every one of these engines has cases where the honest answer is “we cannot tell”. What we do with those cases is the part worth judging us on, so here it is in full.

Contrast we cannot measure is marked unverifiable. Text over a background image, over a gradient, or with a fully transparent ancestor chain has no single true ratio. The finding names which of the three it is and reports no number. It is never counted as a pass, and never quietly composited over white to produce a confident figure.

Undocumented client behaviour is labelled, not invented. Where a lens would have to guess — a resizable reading pane, a per-account Gmail difference — it says the behaviour is unverified instead of applying a transform we cannot source. A missing note is more useful than a fabricated one.

Calibration targets are recorded in the code. The inbox-row specs were fitted against the published character figures that circulate for each client, using one fixed string of average-width English prose. Each spec records which figure it was fitted to and what the fitted width actually achieves, including the cases where character granularity makes the published target unreachable. You can read the reasoning rather than taking the numbers on faith.

Test-only artefacts are labelled. A SpamAssassin check run without a real send has no Received or Relay headers, so those rules fire on every email. We name them as artefacts instead of letting them pad a score.

There is no accuracy percentage anywhere on this site. We could compute one against a corpus we chose ourselves, and it would mean nothing about your email. So we describe the method instead and let you check it.

Credits and sources

  • caniemail.com — the client support dataset behind every per-declaration verdict, maintained by HTeuMeuLeu and contributors and used under the MIT licence. Each finding links to the feature page it came from.
  • Machado, Oliveira and Fernandes (2009), “A Physiologically-based Model for Simulation of Color Vision Deficiency” — the matrices behind the colour-vision lenses, applied in linear light as the model requires.
  • WCAG 2.1 (W3C) — the contrast thresholds and the success criteria each accessibility finding references.
  • RFC 7208 (SPF), RFC 6376 (DKIM), RFC 7489 (DMARC), RFC 7505 (null MX), RFC 8461 (MTA-STS), RFC 8460 (TLS-RPT) — the rules the deliverability check applies.
  • Postmark’s public SpamCheck API — real SpamAssassin scoring for the optional, opt-in spam check.
  • DOMPurify for sanitizing every email before it is rendered, and css-tree for parsing CSS into declarations.
  • Litmus Email Client Market Share (May 2026) for the client family shares used to weight findings. Platform splits within a family are our own estimates and are labelled as such.

More free email tools

Every one of these runs in your browser, needs no account, and has no usage limit.

Method, answered

Why simulate instead of screenshotting real clients?
Because a screenshot has pixels but no model. Once a client has repainted your email, the authored colours and the CSS are gone, so a PNG cannot tell you that a caption resolves to 4.19:1 inside Gmail’s inversion, or which declaration an Outlook version dropped. Keeping the colour model and the CSS is what makes explanations possible — and explanations are what let you fix something. The honest tradeoff is that we cannot show you a pixel-exact Word render, and we say so on this page.
Do you publish an accuracy percentage?
No, and we will not. There is no defensible way to compute one: it would depend on which clients, which emails, which CSS features and which versions you measured against, and any single number would be marketing rather than measurement. Instead we tell you what each transform is based on, and we label anything we cannot verify as unverified.
What does “unverifiable” mean on a contrast finding?
That the effective background genuinely cannot be known from the colour model — text over a background image, over a gradient, or with a fully transparent ancestor chain. The ratio varies across the element, so no honest single number exists. We show the finding, say which of the three cases it is, and refuse to report a ratio. It is never counted as a pass.
Where does the client support data come from?
caniemail.com, maintained by HTeuMeuLeu and contributors, used under the MIT licence. The verdicts are theirs; the parsing of your CSS into individual declarations, and the mapping onto engines and market share, is ours. Every finding links to the caniemail feature page it came from so you can check the primary source rather than trusting our summary.
Should I stop testing on real devices?
No. Treat this as a fast first pass that catches the class of problem you cannot see by eye — contrast after inversion, dropped declarations, truncation, clipping, blocked images — and then test anything high-stakes on the real clients your list actually uses. The two approaches answer different questions, and the honest answer to "which should I use" is both.
Do the tools ever send my email anywhere?
Two exceptions, both explicit. The SpamAssassin score sends your HTML to Postmark’s public SpamCheck service, only when you click the button, and only with an account. The deliverability check reads public DNS records for a domain you type. Everything else — rendering, the client lenses, dark mode, contrast, the transcript, the inbox rows, .eml parsing, clipping — runs inside your browser.

Simulation finds the problems. Review gets the sign-off.

Proofel is the review-and-approval layer these engines were built for: one link, feedback pinned to the pixel, every approval on the record.

14-day all-access trial · no credit card required · reviewers never need an account