Home / Snippets / UI Components /
Image overlay card
Gradient overlay anchors text to the bottom of an image card using absolute positioning — no JavaScript.
Quick implementation
.overlay-card {
position: relative;
border-radius: 0.75rem;
overflow: hidden;
}
.overlay-card__image {
display: block;
width: 100%;
aspect-ratio: 4 / 3;
object-fit: cover;
}
.overlay-card__overlay {
position: absolute;
inset: 0;
background: linear-gradient(
to top,
oklch(0 0 0 / 0.75) 0%,
oklch(0 0 0 / 0.2) 50%,
transparent 100%
);
}
.overlay-card__content {
position: absolute;
bottom: 0;
left: 0;
right: 0;
padding: 1.25rem;
}
.overlay-card__title {
font-size: 1.1rem;
font-weight: 700;
color: oklch(1 0 0);
margin: 0 0 0.25rem;
line-height: 1.3;
}
.overlay-card__text {
font-size: 0.8rem;
color: oklch(0.85 0 0);
margin: 0;
line-height: 1.5;
}
Prompt this to your LLM
Includes role, constraints, two framework variants, and edge cases to handle.
You are a senior frontend engineer building a media card component library.
Goal: An image card with a gradient overlay and text anchored to the bottom — no JavaScript.
Technical constraints:
- Use position: relative on the card wrapper and overflow: hidden to clip the image to border-radius.
- The overlay must use position: absolute with inset: 0 and a linear-gradient(to top, ...) from dark to transparent.
- Use oklch() for all gradient stops — e.g., oklch(0 0 0 / 0.75) for the dark bottom, transparent at the top.
- Use aspect-ratio: 4 / 3 with object-fit: cover on the image so it fills the card regardless of image dimensions.
- The text content must use position: absolute; bottom: 0; left: 0; right: 0 to anchor to the card bottom.
- Text must always be oklch(1 0 0) (white) to ensure legibility over the dark gradient.
Framework variant (pick one):
A) Vanilla CSS BEM classes: .overlay-card, .overlay-card__image, .overlay-card__overlay, .overlay-card__content.
B) React component — accept src, title, and description as props; render the overlay and content internally.
Edge cases to handle:
- Portrait images should not distort — rely on object-fit: cover, not fixed height.
- Card must not overflow its grid cell when placed in a CSS grid layout.
- Overlay div must have aria-hidden="true" so screen readers skip the decorative gradient.
Return CSS.
Why this matters in 2026
Image overlay cards are a staple of editorial, e-commerce, and portfolio layouts — blog grids, product tiles, and photo galleries all use this pattern. Getting the gradient right ensures text is legible over any image, regardless of photo brightness. A CSS-only implementation using position: absolute and linear-gradient is lighter and more composable than JavaScript-based text-shadow hacks or filter overlays.
The logic
position: relative on the card wrapper creates a stacking context so the position: absolute overlay and content children are anchored to the card rather than the viewport. overflow: hidden clips the image to the card's border-radius, ensuring no corners bleed out. The linear-gradient(to top, oklch(0 0 0 / 0.75) 0%, transparent 100%) fades from an opaque dark layer at the bottom — where the text sits — to fully transparent at the top, preserving the image detail while guaranteeing readable contrast. inset: 0 is shorthand for top: 0; right: 0; bottom: 0; left: 0, stretching the overlay to cover the entire card.
Accessibility & performance
Add aria-hidden="true" to the overlay element so assistive technologies skip the decorative gradient layer. Ensure the <img> has a meaningful alt attribute — the overlay is not a substitute for image description. White text on a 75% opaque black gradient typically achieves well above the 4.5:1 WCAG contrast ratio, but validate with real images where the gradient might be thinner. Use object-fit: cover with aspect-ratio to prevent layout shift as images load.