Text over a picture you do not control
Why this is harder than it looks
A contrast ratio is computed between two colours. An image has thousands. So there is no single ratio for white text over a photograph, and the requirement still applies — which means, in practice, that the worst pixel under the text governs whether it is legible.
This would be manageable if you chose every image. Usually you do not. The image comes from a content management system, a user upload, a client's library, or a stock search performed by somebody else six months from now. The design has to work for an image nobody has seen yet.
That constraint rules out the most elegant solution and forces one of the robust ones.
Five approaches, from best to worst
1. Put the text in a plain region of the image. Costs nothing, looks best, and only works when you control the image. A sky, a wall, a shallow-focus background. If you are art-directing a specific photograph, brief for it: ask for space in the frame.
2. A solid panel behind the text. The most reliable option available. The ratio becomes computable because the text sits on a known colour. It looks deliberate rather than apologetic, and it is what newspapers and posters have always done. The objection is that it covers part of the image, which is only an objection if the image is more important than the words.
3. A gradient scrim. A gradient from transparent to dark, over the region carrying the text. The standard compromise, and it works because it is strongest exactly where the text is and disappears where it is not.
.hero::after {
content: '';
position: absolute;
inset: 0;
background: linear-gradient(
to top,
rgb(0 0 0 / 0.75) 0%,
rgb(0 0 0 / 0.45) 25%,
rgb(0 0 0 / 0) 55%
);
}Three stops rather than two matters: a straight two-stop gradient has a visible linear ramp that reads as a band. Easing it with an intermediate stop makes it look like light rather than like a rectangle.
4. A full overlay. A flat dark layer over the whole image at 40 to 60%. Reliable, and it dulls the photograph everywhere including where nothing needed dulling. Acceptable when the image is atmosphere rather than content.
5. Text shadow. The weakest, and the one reached for first. A shadow adds a dark halo around each glyph, which helps marginally against a light background and makes the text look muddy at any size. It also fails completely on a busy background, where the halo merges with the detail. Use it as a small addition to one of the above, never on its own.
A sixth option worth knowing: backdrop-filter: blur(12px) blurs whatever is behind an element, which turns a busy background into a smooth one under the text while leaving the rest of the image sharp. Support is now broad, it is expensive to render on low-end devices, and it needs a translucent background colour alongside it to guarantee the ratio.
Checking the worst case
A routine that takes a minute:
- Find the lightest pixel in the region under white text, using the colour picker in any editor.
- Compute the ratio against your text colour.
- Repeat with the darkest pixel if your text is dark.
Then do it again with the worst plausible image rather than the chosen one — a white sky, a snow scene, a photograph of a document. If the design holds for that, it holds.
For a system where images are uploaded by users, the honest answer is that a scrim tuned to a nice photograph will fail on somebody's picture of a whiteboard, and the panel is the correct choice.
Placement
Two practical points that reduce how much scrim you need in the first place.
Put the text where the image is already quiet. Even with an unknown image, the bottom of a photograph is more often darker and less detailed than the middle, which is why so many cards put their text there.
Keep text out of the centre. The centre is where the subject usually is, so text there covers the subject and sits on the busiest region. Top and bottom bands are safer on both counts.
The accessibility position
WCAG applies to text over images exactly as it applies to text on a flat background, and there is no exemption for decorative photography. If the text is content, it needs its ratio.
What the guidelines do not require is that the image be unaltered. A scrim is a legitimate solution, a panel is a legitimate solution, and moving the text off the image entirely is a legitimate solution. The one thing that is not available is deciding that a photograph is more important than whether people can read the words on it.
The one thing to keep
An image has no single contrast ratio, so the worst pixel under the text governs legibility — and because the image is usually unknown in advance, a solid panel or a multi-stop gradient scrim is the robust choice and a text shadow alone is not.
Before you move on
A card component places white text over user-uploaded photographs with a two-stop gradient scrim tuned against the sample images. Complaints arrive about unreadable cards. What is the most defensible fix?
Pick the one you would defend. Nobody sees your answer.