Text Overlay on Images and Gradients

Ensure text layered on images, videos, or gradient backgrounds meets WCAG contrast requirements. Learn overlay techniques that guarantee accessible text readability.

Accessibility Tips

Detailed Explanation

Making Text Readable Over Images

Placing text directly over images or videos is a popular design pattern for hero sections, banners, and cards. The challenge is that image content varies, making consistent contrast impossible without an overlay technique.

The Overlay Solution

Add a semi-transparent overlay between the image and the text:

.hero {
  position: relative;
}

.hero-image {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

/* Dark overlay for white text */
.hero::before {
  content: "";
  position: absolute;
  inset: 0;
  background: rgba(0, 0, 0, 0.55);
  /* Ensures approximately 4.5:1 for white text
     on most image backgrounds */
}

.hero-text {
  position: relative;
  color: #ffffff;
  z-index: 1;
}

Overlay Opacity Guide

The required overlay opacity depends on the text color and the typical image brightness:

Text Color Overlay Color Min Opacity Approximate Ratio
White Black 0.55 ~4.5:1 (AA)
White Black 0.70 ~7:1 (AAA)
Black White 0.55 ~4.5:1 (AA)
Black White 0.70 ~7:1 (AAA)

Gradient Overlay Alternative

A gradient overlay can be more visually appealing:

.hero::before {
  background: linear-gradient(
    to top,
    rgba(0, 0, 0, 0.8) 0%,
    rgba(0, 0, 0, 0.4) 50%,
    rgba(0, 0, 0, 0.0) 100%
  );
}

/* Place text at the bottom where overlay is strongest */
.hero-text {
  position: absolute;
  bottom: 2rem;
  color: #ffffff;
}

Testing Strategy

Since image content varies, test your overlay against:

  1. A mostly white/bright image
  2. A mostly dark image
  3. A mixed/busy image

If white text passes contrast on the bright image with your overlay, it will pass on darker images too. The challenge is finding the minimum overlay opacity that works for the brightest expected content.

Alternative: Text Container

Instead of an overlay, place text in an opaque container:

.hero-text {
  background: rgba(0, 0, 0, 0.85);
  color: #ffffff;
  padding: 1rem 1.5rem;
  border-radius: 0.5rem;
}

Use Case

Use these techniques for hero sections, banner images, video backgrounds, card overlays, and any layout where text is placed over variable visual content. Test with multiple image backgrounds to ensure reliability.

Try It — Accessibility Color Checker

Open full tool