Type Contrast That Passes an Accessibility Review
Generated graphics fail contrast because the model optimized for looking good, not for a ratio. The actual thresholds, the exemptions, and a two-minute check.
A generated poster looks finished — soft gray headline over a warm pastel background, tasteful, on-brand, exactly the restrained look you asked for. Run it through a contrast checker and the headline measures 2.3:1. It fails an accessibility review outright, and nothing about the failure is visible just by looking at it, because the model wasn't optimizing for a ratio in the first place. It was optimizing for "looks good," trained on a world of design work that treats low-contrast type as a legitimate aesthetic choice constantly — moody, editorial, restrained. Nothing in a typical prompt tells it that this particular headline actually needs to be readable by someone with low vision, so nothing stops it from producing a combination that a human eye reads as tasteful and a contrast checker reads as broken.
Why generated type fails this by default
The gap isn't a bug in any specific model — it's a mismatch between what "looks good" and "meets the threshold" actually mean, and generated design sits closer to the first than the second unless something explicitly steers it otherwise. A lot of genuinely appealing design work — muted type on a photo, thin light-gray captions, pastel-on-pastel palettes — reads as sophisticated precisely because it's understated, and understated correlates strongly with low contrast. A model trained on that aesthetic has no built-in reason to prefer the higher-contrast version; nobody labeled the training data "this one passes AA and this one doesn't." Contrast compliance is an external, measurable constraint layered on top of a generation, not something the generation is inherently steering toward.
The actual numbers, not a vibe
WCAG 2.2's Success Criterion 1.4.3, level AA, sets an objective floor: text and images of text need at least a 4.5:1 contrast ratio against their background. That relaxes for large-scale text — at least 18 point, or 14 point bold, per WCAG's own technique for meeting the requirement — down to 3:1. Both numbers are measurable with a color picker and a calculator; there's no "close enough" or "reads fine to me" in either one, which is exactly what makes this checkable in a way "does this feel legible" never was.
The size threshold is worth internalizing precisely, because it changes which number actually applies. A body-copy caption at 16px doesn't qualify as large-scale — it needs the full 4.5:1. A bold, oversized headline at 24px or larger does qualify, and only needs 3:1. The same color pairing can pass on a headline and fail on the caption sitting directly underneath it, purely because of the size difference — which means a single generated graphic can need two different checks, not one blanket pass.
What's actually exempt, and why the line matters
Two categories are explicitly carved out of the requirement, and getting this distinction right matters in both directions — over-applying the rule wastes effort fixing something that was never broken, and under-applying it lets a real failure hide behind a fig leaf:
- Text that's part of a logo or brand name has no contrast requirement at all. A wordmark rendered in a specific brand color against a background that happens to sit under 4.5:1 isn't a violation — the standard explicitly exempts logotype text from the check entirely.
- Purely decorative or incidental text is also exempt — text that's part of an inactive UI element, not meant to be read, or embedded in a photo where it's not the point of the image.
What's not covered by either exemption: a CTA, a caption, a headline, a price, a disclaimer, anything an actual reader needs to read to get the message the graphic exists to deliver. It's tempting to wave a low-contrast headline through as "stylistic," but a headline is doing informational work a logotype isn't — it needs the full check, and dressing it up as decoration doesn't change that.
The two-minute check
Contrast measurement is fast precisely because it doesn't require judgment once you have the two actual colors in hand — the discipline is making sure you're measuring the right two colors:
- Sample the rendered text color, not the color you asked for. A prompt requesting "white text" can render slightly off-white, or anti-aliased edges can shift the effective color at small sizes. Pull the actual pixel value with a color picker rather than trusting what you typed.
- Sample the worst-case background, not the average. Text sitting over a photo, a gradient, or a busy generated scene doesn't have one background color — it has a range, and the ratio that matters is the one at the lowest-contrast point under the text, not wherever the background happens to look darkest or lightest on average. A caption that clears 4.5:1 over the shadowed left side of an image and drops to 2:1 over a bright patch on the right still fails, because a reader encounters the whole line at once.
- Run the two sampled values through any WCAG contrast calculator and check the result against the correct threshold for that text's actual point size — 4.5:1 for anything under the large-scale cutoff, 3:1 at or above it.
- Recheck after any background change, not just after a color change to the type itself. Swapping the photo behind a caption can break contrast just as easily as changing the text color did, and it's the change most likely to get skipped in a review because "the text didn't move."
Where this bites hardest in generated content
Flat-color brand cards are the easy case — one background color, one text color, check once and it holds everywhere. Generated content rarely stays that simple. Text sitting over a photographic or fully generated scene has a background that varies across the text's own footprint, which is exactly the case step two above exists for. Burned-in video captions compound this further: the background isn't one image, it's a different frame every few seconds, so a caption style that passes comfortably over one shot can fail outright three seconds later over a brighter or busier one.
This is precisely why caption presets built for video lean on outline strokes and background plates rather than color alone — a white caption with a solid dark outline, or one sitting on a semi-opaque background bar, holds its contrast regardless of what's moving behind it in the footage. Versely's caption style presets expose exactly these levers — outline color and width, background color, position — because color-only contrast is the one caption approach that can't survive a moving background without constant re-checking shot to shot.
Fixing a fail without a redesign
A failing ratio rarely needs a new composition — it needs one of a handful of small, specific changes:
- Add an outline or stroke around the text, which restores contrast against a busy or variable background without touching the fill color at all.
- Add a background plate or scrim — a solid or semi-opaque bar behind the text — which turns a variable photographic background into a flat, predictable one for contrast purposes.
- Cross the size threshold deliberately. Bumping a caption from 16px to a genuinely large-scale weight and size can drop the requirement from 4.5:1 to 3:1, which is sometimes enough on its own to turn a marginal fail into a clean pass.
- Change the type color, not the whole palette. Contrast failures are usually fixable by adjusting one color in isolation rather than reworking the composition the rest of the design is built around.
A Versely walkthrough
The most durable fix is upstream of any single generation: lock a caption style and a brand palette that already clear the threshold, so every asset generated afterward inherits a passing combination by default instead of needing an individual check.
- Set the brand kit's caption style once, choosing a preset built around an outline or background plate rather than color alone — the version that survives a moving or photographic background without a per-video recheck. Set my brand kit stores this alongside your brand's colors and fonts so it's applied automatically to what gets generated afterward, not re-selected per asset.
- Generate the graphic or video as usual, then sample the actual rendered text and background colors before publish — the two-minute check above, run once per new composition rather than trusted from the prompt alone.
- If it fails, adjust the lever that's cheapest for the specific asset — an outline for a photographic background, a size bump for a borderline body caption, a background plate for anything with a genuinely busy scene behind the text.
- Browse Versely's font library for weights that hold up cleanly at the large-scale size threshold, and check the model catalog for which generators are producing type your brand can actually ship without a rework pass.
FAQ
Does a logo really have no contrast requirement at all?
Correct — text that's part of a logo or brand name is explicitly exempt from WCAG's contrast success criterion. That exemption doesn't extend to a tagline, CTA, or any other text sitting near the logo; only the logotype itself is carved out.
What counts as "large-scale" text for the relaxed 3:1 threshold?
At least 18 point, or at least 14 point if the text is bold. Below that size, even bold text needs the full 4.5:1 — the relaxed threshold is tied to actual rendered size and weight, not to how important the text looks in the layout.
Is a low-contrast look ever acceptable?
For text that's genuinely decorative or incidental — not meant to convey information a reader needs — yes, it's exempt. For anything doing real communication work in the design (a headline, a CTA, a caption), the threshold applies regardless of how deliberate or tasteful the low-contrast choice looks.
Why would the same text pass in one part of an image and fail in another?
Because the background isn't one color. Text sitting over a photo, gradient, or generated scene needs to be checked against its lowest-contrast point, not an average — a caption can clear the threshold over a dark area and fail over a brighter patch a few words later in the same line.
Two colors, one calculator, one number to clear — it's the fastest accessibility check in the entire pipeline, and the easiest one to skip because a generated graphic never tells you it's about to fail.