TechCompare LogoTechCompare

How to make text readable over background images: contrast tips for hero sections

Always add a scrim or gradient overlay behind text on background images. A 40-60% black overlay is the industry standard. Test your result using a contrast checker on screenshots of the actual rendered page, not just the source colors. If you're not willing to darken the image, move the text off the image entirely.

Text over a background image is the most common accessibility failure on the web. Unlike a solid background where you can calculate an exact contrast ratio, images have varying brightness across the surface. White text that's perfectly readable over a dark portion of the photo becomes invisible over a bright sky, and the WCAG contrast formula wasn't designed for this scenario.

By TechCompare · Updated

WCAG level
WCAG AA
Minimum contrast (4.5:1+)
Example ratio
21.0:1
#FFFFFF on #000000
Category
Practical Tips
Accessibility knowledge base

How this is calculated

The practical solution is to add a scrim: a semi-transparent dark overlay between the image and the text. A black overlay at 40-60% opacity is usually enough to ensure white text remains readable across the entire image. CSS gradient overlays (linear-gradient) let you darken just the portion of the image that sits behind text, preserving the image's impact elsewhere. The key principle: if you can't guarantee the background under every character of text, add an overlay that makes the effective background uniform.

Verdict

The structural issue is that the WCAG contrast formula assumes a single background luminance, but a photo's brightness varies per pixel, so white text readable against a dark sky becomes invisible against a bright cloud. Scrim overlays solve this by forcing the effective background toward a uniform luminance: a flat 60% black overlay reliably pushes white text past 4.5:1 against almost any natural photo, while a linear-gradient overlay darkens only the slice of the image directly behind the text and preserves the visual impact elsewhere. The honest operational rule is to validate against a screenshot of the rendered page at its worst-case bright pixel, not against the source colors, since the contrast test only works against the actual background each character sits on. If you can't commit to the scrim, move the text off the image.

More Contrast scenarios

Frequently asked questions

How do I check contrast on a gradient background?
Sample the background color directly behind the text at its lightest point. Contrast ratio is measured per-pixel, so use the worst-case (lightest) background under any character of the text for a passing result.
How do I add a scrim overlay behind text on a hero image in CSS?
Use `background: linear-gradient(rgba(0,0,0,0.6), rgba(0,0,0,0.6))` on the container behind the text, layered on top of the image. Or use `background-color: rgba(0,0,0,0.5)` for a flat scrim. The 50-60% opacity range reliably takes white text past 4.5:1 against almost any photo background.
What is the minimum scrim opacity for AA compliance?
It depends on the underlying image's worst-case brightness. For most natural photos with bright skies or backlit areas, 60% black on the entire image is the practical minimum. For spot scrims that only darken a portion of the image behind text, a gradient to a darker area often needs less opacity. Always test rendered output, not just design-time samples.