HTML & CSS
Use a Linear Gradient Over an HTML Image
Overlay a linear gradient on an HTML image with a wrapper and pseudo-element, preserve meaningful alt text, and control cropping without fading the caption.
Keep meaningful images in the document
To use a linear gradient with an HTML image, wrap the image, paint the gradient on a positioned pseudo-element, and place any caption above that decorative layer. The image remains an img element, so you can retain its alt text, width and height attributes, and responsive image sources. This is useful when the photograph itself contributes to the content.
Do not apply opacity to the whole wrapper to make the overlay transparent. That would also fade the image, caption and any interactive descendants. Transparency belongs in the gradient’s colors. Likewise, a background-image placed directly on an opaque img element is behind its image content and will not become a visible overlay above it.
Add a caption without replacing the image semantics
The example uses the figure itself as a positioned wrapper. Replace the sample URL and alt text together so the description matches your actual photograph. The caption adds context rather than mechanically repeating the alternative text. The gradient is generated content with no textual content of its own.
<figure class="route-figure route-image">
<img src="/images/ridge.jpg" width="1200" height="800"
alt="A footpath crossing a mountain ridge">
<figcaption>The ridge route, viewed from its western approach.</figcaption>
</figure>
.route-figure { max-width: 48rem; margin: 1rem auto; }
.route-image {
display: grid;
position: relative;
isolation: isolate;
overflow: hidden;
background: #172554;
}
.route-image img {
display: block;
grid-area: 1 / 1;
width: 100%;
height: 100%;
min-height: 18rem;
object-fit: cover;
object-position: 60% center;
}
.route-image::after {
content: "";
position: absolute;
inset: 0;
z-index: 1;
pointer-events: none;
background: linear-gradient(to bottom, rgb(0 0 0 / 0) 30%, rgb(0 0 0 / .9));
}
.route-image figcaption {
grid-area: 1 / 1;
align-self: end;
position: relative;
z-index: 2;
padding: 1.25rem;
color: #ffffff;
background: #172554;
}
The caption has an opaque dark background as an additional safeguard. That surface gives multi-line text a predictable reading area even when the photograph changes. The gradient still softens the image’s transition toward the caption. If your design removes that solid surface, assess contrast over every part of the replacement photograph that can appear behind the caption.
Let the content influence the available height
The image and caption occupy the same grid area, while the pseudo-element covers the wrapper. The image has a minimum displayed height, and the caption remains a layout participant. Test unusually long captions and larger text instead of assuming that one short sample establishes the behavior of all content.
Object-fit: cover preserves the photograph’s proportions while cropping the part that does not fit its box. It does not stretch the picture to a different aspect ratio. Move object-position to keep the important subject visible. The object-fit reference explains the difference between cover, contain and fill.
If you add srcset and sizes, keep their candidate widths consistent with the real files you provide. The gradient still belongs to the figure and does not need to be duplicated for every image candidate. Inspect the selected currentSrc in the browser when testing a blurry phone image; that separates a resource-selection problem from a problem in the overlay.
Keep figcaption as the first or last child of figure when adapting the markup. Moving it into an arbitrary inner div changes the HTML structure expected for a figure caption, even if the CSS happens to paint it in the same position.
Use the generator only for the gradient value
Open the CSS Gradient Generator to experiment with a linear direction and two opaque colors. Copy the gradient value, then adapt its stops to transparent and dark alpha colors in your pseudo-element. The generator does not wrap an image, create alt text, add a caption or choose its stacking order.
For a simple decorative background instead of a meaningful image, a comma-separated gradient and URL can be shorter. That alternative has a different accessibility role, so choose it based on what the image communicates. The W3C informative-image guidance explains how the surrounding context determines an appropriate text alternative.
Inspect the correct layer when the result is wrong
If no overlay appears, inspect the wrapper’s ::after rule and confirm that content is an empty string rather than omitted, that its box has nonzero dimensions, and that background-image is a gradient. If the caption disappears, compare the stacking levels instead of increasing the darkness of the gradient.
If an image looks distorted, check its computed object-fit and the box dimensions. If a link in a customized caption cannot be clicked, check that the decorative pseudo-element still has pointer-events: none. Finish by testing a loaded image, a failed image request and a long caption at phone width, so the result works beyond its ideal screenshot.


