07 / 20
All 20 in 20 Tailwind CSS Image Hover Effects
- 01Tailwind Image Hover Zoom In Card
- 02Tailwind Hover Reveal Text Over Image
- 03Tailwind E-Commerce Product Image Swap on Hover
- 04Tailwind Grid Image Blur Overlay Text Hover
- 05Tailwind Card Slide Up Caption on Hover
- 06Tailwind Grayscale to Color Image Hover
- 07Tailwind Image Color Overlay Tint on Hover
- 08Tailwind Neumorphic Image Card Hover Effect
- 09Tailwind Glassmorphism Overlay on Image Hover
- 10Tailwind Glowing Neon Border Image Hover
- 11Tailwind Image Clip-Path Transition Hover
- 12Tailwind Image Tilt 3D Perspective Hover
- 13Tailwind Shining Light Glare Image Hover
- 14Tailwind Image Split Transition Hover
- 15Tailwind Image Ripple Animation Hover
- 16Tailwind Circular Team Profile Avatar Hover
- 17Tailwind Fullscreen Background Image Hover
- 18Tailwind Masonry Gallery Zoom Hover
- 19Tailwind Image Icon Reveal Center Hover
- 20Tailwind Image Card Flip 3D Animation Hover
Tailwind Image Color Overlay Tint on Hover
A brand colour washed over a photograph with mix-blend-color, which replaces hue and saturation while keeping luminosity — a lighting gel, not a paint bucket. The tint is a per-card inline custom property, so the overlay is one class list serving any colour, and the text sits in an isolate wrapper so the blend cannot touch it.
Untitled UI Pro: 5,000+ React + Tailwind CSS v4 components · from $349 one-time
Untitled UI React · Affiliate link
The code
<section class="tih-07 w-full min-h-svh grid place-items-center bg-tih07-bg font-tih07-sans px-6 py-10" aria-label="Colour overlay tint on hover demo">
<div class="grid w-full max-w-195 gap-4 grid-cols-1 sm:grid-cols-3">
<article style="--tint:oklch(0.7 0.19 45)" class="group relative overflow-hidden rounded-[14px] aspect-square">
<div class="absolute inset-0 grid place-items-center bg-[image:url('https://picsum.photos/seed/landscape-orange/600/600'),linear-gradient(135deg,oklch(0.27_0.03_265),oklch(0.35_0.02_265),oklch(0.45_0.015_265))] bg-cover bg-center bg-no-repeat transition-transform duration-380 ease-tih07 group-hover:scale-106 motion-reduce:transition-none motion-reduce:group-hover:scale-100">
</div>
<div class="absolute inset-0 bg-[var(--tint)] mix-blend-color opacity-0 transition-opacity duration-380 ease-tih07 group-hover:opacity-70 motion-reduce:transition-none motion-reduce:opacity-50"></div>
<span class="absolute top-2.5 left-2.5 z-2 isolate px-2 py-0.75 rounded-md text-[10px] font-semibold text-tih07-muted bg-[oklch(1_0_0/0.08)] border border-[oklch(1_0_0/0.1)]">Brand A</span>
<div class="absolute inset-0 z-2 isolate grid place-items-center">
<p class="text-sm font-bold text-tih07-text opacity-0 scale-90 transition-[opacity,scale] duration-380 ease-tih07 group-hover:opacity-100 group-hover:scale-100 motion-reduce:transition-none motion-reduce:opacity-100 motion-reduce:scale-100">Ember Orange Tint</p>
</div>
</article>
<article style="--tint:oklch(0.62 0.19 255)" class="group relative overflow-hidden rounded-[14px] aspect-square">
<div class="absolute inset-0 grid place-items-center bg-[image:url('https://picsum.photos/seed/landscape-blue/600/600'),linear-gradient(135deg,oklch(0.14_0_0),oklch(0.22_0_0),oklch(0.3_0_0))] bg-cover bg-center bg-no-repeat transition-transform duration-380 ease-tih07 group-hover:scale-106 motion-reduce:transition-none motion-reduce:group-hover:scale-100">
</div>
<div class="absolute inset-0 bg-[var(--tint)] mix-blend-color opacity-0 transition-opacity duration-380 ease-tih07 group-hover:opacity-70 motion-reduce:transition-none motion-reduce:opacity-50"></div>
<span class="absolute top-2.5 left-2.5 z-2 isolate px-2 py-0.75 rounded-md text-[10px] font-semibold text-tih07-muted bg-[oklch(1_0_0/0.08)] border border-[oklch(1_0_0/0.1)]">Brand B</span>
<div class="absolute inset-0 z-2 isolate grid place-items-center">
<p class="text-sm font-bold text-tih07-text opacity-0 scale-90 transition-[opacity,scale] duration-380 ease-tih07 group-hover:opacity-100 group-hover:scale-100 motion-reduce:transition-none motion-reduce:opacity-100 motion-reduce:scale-100">Pacific Blue Tint</p>
</div>
</article>
<article style="--tint:oklch(0.62 0.21 295)" class="group relative overflow-hidden rounded-[14px] aspect-square">
<div class="absolute inset-0 grid place-items-center bg-[image:url('https://picsum.photos/seed/landscape-violet/600/600'),linear-gradient(135deg,oklch(0.16_0.01_285),oklch(0.21_0.015_285),oklch(0.29_0.02_285))] bg-cover bg-center bg-no-repeat transition-transform duration-380 ease-tih07 group-hover:scale-106 motion-reduce:transition-none motion-reduce:group-hover:scale-100">
</div>
<div class="absolute inset-0 bg-[var(--tint)] mix-blend-color opacity-0 transition-opacity duration-380 ease-tih07 group-hover:opacity-70 motion-reduce:transition-none motion-reduce:opacity-50"></div>
<span class="absolute top-2.5 left-2.5 z-2 isolate px-2 py-0.75 rounded-md text-[10px] font-semibold text-tih07-muted bg-[oklch(1_0_0/0.08)] border border-[oklch(1_0_0/0.1)]">Brand C</span>
<div class="absolute inset-0 z-2 isolate grid place-items-center">
<p class="text-sm font-bold text-tih07-text opacity-0 scale-90 transition-[opacity,scale] duration-380 ease-tih07 group-hover:opacity-100 group-hover:scale-100 motion-reduce:transition-none motion-reduce:opacity-100 motion-reduce:scale-100">Deep Violet Tint</p>
</div>
</article>
</div>
</section><section class="tih-07 w-full min-h-svh grid place-items-center bg-tih07-bg font-tih07-sans px-6 py-10" aria-label="Colour overlay tint on hover demo">
<div class="grid w-full max-w-195 gap-4 grid-cols-1 sm:grid-cols-3">
<article style="--tint:oklch(0.7 0.19 45)" class="group relative overflow-hidden rounded-[14px] aspect-square">
<div class="absolute inset-0 grid place-items-center bg-[image:url('https://picsum.photos/seed/landscape-orange/600/600'),linear-gradient(135deg,oklch(0.27_0.03_265),oklch(0.35_0.02_265),oklch(0.45_0.015_265))] bg-cover bg-center bg-no-repeat transition-transform duration-380 ease-tih07 group-hover:scale-106 motion-reduce:transition-none motion-reduce:group-hover:scale-100">
</div>
<div class="absolute inset-0 bg-[var(--tint)] mix-blend-color opacity-0 transition-opacity duration-380 ease-tih07 group-hover:opacity-70 motion-reduce:transition-none motion-reduce:opacity-50"></div>
<span class="absolute top-2.5 left-2.5 z-2 isolate px-2 py-0.75 rounded-md text-[10px] font-semibold text-tih07-muted bg-[oklch(1_0_0/0.08)] border border-[oklch(1_0_0/0.1)]">Brand A</span>
<div class="absolute inset-0 z-2 isolate grid place-items-center">
<p class="text-sm font-bold text-tih07-text opacity-0 scale-90 transition-[opacity,scale] duration-380 ease-tih07 group-hover:opacity-100 group-hover:scale-100 motion-reduce:transition-none motion-reduce:opacity-100 motion-reduce:scale-100">Ember Orange Tint</p>
</div>
</article>
<article style="--tint:oklch(0.62 0.19 255)" class="group relative overflow-hidden rounded-[14px] aspect-square">
<div class="absolute inset-0 grid place-items-center bg-[image:url('https://picsum.photos/seed/landscape-blue/600/600'),linear-gradient(135deg,oklch(0.14_0_0),oklch(0.22_0_0),oklch(0.3_0_0))] bg-cover bg-center bg-no-repeat transition-transform duration-380 ease-tih07 group-hover:scale-106 motion-reduce:transition-none motion-reduce:group-hover:scale-100">
</div>
<div class="absolute inset-0 bg-[var(--tint)] mix-blend-color opacity-0 transition-opacity duration-380 ease-tih07 group-hover:opacity-70 motion-reduce:transition-none motion-reduce:opacity-50"></div>
<span class="absolute top-2.5 left-2.5 z-2 isolate px-2 py-0.75 rounded-md text-[10px] font-semibold text-tih07-muted bg-[oklch(1_0_0/0.08)] border border-[oklch(1_0_0/0.1)]">Brand B</span>
<div class="absolute inset-0 z-2 isolate grid place-items-center">
<p class="text-sm font-bold text-tih07-text opacity-0 scale-90 transition-[opacity,scale] duration-380 ease-tih07 group-hover:opacity-100 group-hover:scale-100 motion-reduce:transition-none motion-reduce:opacity-100 motion-reduce:scale-100">Pacific Blue Tint</p>
</div>
</article>
<article style="--tint:oklch(0.62 0.21 295)" class="group relative overflow-hidden rounded-[14px] aspect-square">
<div class="absolute inset-0 grid place-items-center bg-[image:url('https://picsum.photos/seed/landscape-violet/600/600'),linear-gradient(135deg,oklch(0.16_0.01_285),oklch(0.21_0.015_285),oklch(0.29_0.02_285))] bg-cover bg-center bg-no-repeat transition-transform duration-380 ease-tih07 group-hover:scale-106 motion-reduce:transition-none motion-reduce:group-hover:scale-100">
</div>
<div class="absolute inset-0 bg-[var(--tint)] mix-blend-color opacity-0 transition-opacity duration-380 ease-tih07 group-hover:opacity-70 motion-reduce:transition-none motion-reduce:opacity-50"></div>
<span class="absolute top-2.5 left-2.5 z-2 isolate px-2 py-0.75 rounded-md text-[10px] font-semibold text-tih07-muted bg-[oklch(1_0_0/0.08)] border border-[oklch(1_0_0/0.1)]">Brand C</span>
<div class="absolute inset-0 z-2 isolate grid place-items-center">
<p class="text-sm font-bold text-tih07-text opacity-0 scale-90 transition-[opacity,scale] duration-380 ease-tih07 group-hover:opacity-100 group-hover:scale-100 motion-reduce:transition-none motion-reduce:opacity-100 motion-reduce:scale-100">Deep Violet Tint</p>
</div>
</article>
</div>
</section>@import "tailwindcss";
@theme {
--color-tih07-bg: #0d0d0f;
--color-tih07-bg: oklch(0.15 0.004 285);
--color-tih07-text: #f1f5f9;
--color-tih07-text: oklch(0.96 0.005 250);
--color-tih07-muted: #94a3b8;
--color-tih07-muted: oklch(0.7 0.03 250);
--color-tih07-acc: #f97316;
--color-tih07-acc: oklch(0.7 0.19 45);
--font-tih07-sans: 'Space Grotesk', system-ui, sans-serif;
--ease-tih07: cubic-bezier(0.25, 0.46, 0.45, 0.94);
}
/* Root rule: the full-bleed contract, stated in CSS as well as in the markup's
w-full min-h-svh, so the stage is correctly sized before the browser build compiles. */
.tih-07 {
width: 100%;
min-height: 100svh;
}
.tih-07 ::selection {
background: oklch(0.7 0.19 45);
color: #000;
}@import "tailwindcss";
@theme {
--color-tih07-bg: #0d0d0f;
--color-tih07-bg: oklch(0.15 0.004 285);
--color-tih07-text: #f1f5f9;
--color-tih07-text: oklch(0.96 0.005 250);
--color-tih07-muted: #94a3b8;
--color-tih07-muted: oklch(0.7 0.03 250);
--color-tih07-acc: #f97316;
--color-tih07-acc: oklch(0.7 0.19 45);
--font-tih07-sans: 'Space Grotesk', system-ui, sans-serif;
--ease-tih07: cubic-bezier(0.25, 0.46, 0.45, 0.94);
}
/* Root rule: the full-bleed contract, stated in CSS as well as in the markup's
w-full min-h-svh, so the stage is correctly sized before the browser build compiles. */
.tih-07 {
width: 100%;
min-height: 100svh;
}
.tih-07 ::selection {
background: oklch(0.7 0.19 45);
color: #000;
}Setup — do this once per project
Skip this if your project already runs Tailwind v4.
<script src="https://cdn.jsdelivr.net/npm/@tailwindcss/browser@4"></script>
<script src="https://cdn.jsdelivr.net/npm/@tailwindcss/browser@4"></script>Compiles in the browser — perfect for a CodePen or a quick test, not for production.
npm install tailwindcss @tailwindcss/vite
npm install tailwindcss @tailwindcss/vite// vite.config.js ("type": "module" in package.json)
import { defineConfig } from 'vite'
import tailwindcss from '@tailwindcss/vite'
export default defineConfig({
plugins: [tailwindcss()],
})// vite.config.js ("type": "module" in package.json)
import { defineConfig } from 'vite'
import tailwindcss from '@tailwindcss/vite'
export default defineConfig({
plugins: [tailwindcss()],
})Any v4 setup works — Vite, PostCSS or the CLI. Nothing in this demo is bundler-specific.
@import "tailwindcss";
@theme {
--color-tih07-bg: #0d0d0f;
--color-tih07-bg: oklch(0.15 0.004 285);
--color-tih07-text: #f1f5f9;
--color-tih07-text: oklch(0.96 0.005 250);
--color-tih07-muted: #94a3b8;
--color-tih07-muted: oklch(0.7 0.03 250);
--color-tih07-acc: #f97316;
--color-tih07-acc: oklch(0.7 0.19 45);
--font-tih07-sans: 'Space Grotesk', system-ui, sans-serif;
--ease-tih07: cubic-bezier(0.25, 0.46, 0.45, 0.94);
}
/* Root rule: the full-bleed contract, stated in CSS as well as in the markup's
w-full min-h-svh, so the stage is correctly sized before the browser build compiles. */
.tih-07 {
width: 100%;
min-height: 100svh;
}
.tih-07 ::selection {
background: oklch(0.7 0.19 45);
color: #000;
}@import "tailwindcss";
@theme {
--color-tih07-bg: #0d0d0f;
--color-tih07-bg: oklch(0.15 0.004 285);
--color-tih07-text: #f1f5f9;
--color-tih07-text: oklch(0.96 0.005 250);
--color-tih07-muted: #94a3b8;
--color-tih07-muted: oklch(0.7 0.03 250);
--color-tih07-acc: #f97316;
--color-tih07-acc: oklch(0.7 0.19 45);
--font-tih07-sans: 'Space Grotesk', system-ui, sans-serif;
--ease-tih07: cubic-bezier(0.25, 0.46, 0.45, 0.94);
}
/* Root rule: the full-bleed contract, stated in CSS as well as in the markup's
w-full min-h-svh, so the stage is correctly sized before the browser build compiles. */
.tih-07 {
width: 100%;
min-height: 100svh;
}
.tih-07 ::selection {
background: oklch(0.7 0.19 45);
color: #000;
}<link rel="preconnect" href="https://fonts.googleapis.com"> <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin> <link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Space+Grotesk:wght@400;500;600;700&family=JetBrains+Mono:wght@400;500;600&display=swap">
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Space+Grotesk:wght@400;500;600;700&family=JetBrains+Mono:wght@400;500;600&display=swap">What changed in the port
Which parts became utilities, which stayed CSS, and why.
- Three
:nth-childrules assigning--tint-colorbecome three inlinestyle="--tint:…"attributes. The overlay's class list is identical on all three cards, and a CMS can drive the colour without touching CSS. mix-blend-mode: coloris a plain utility (mix-blend-color), andisolation: isolateisisolate— the CSS version's two biggest gotchas both have one-word utility answers.- The layered photo-over-gradient background becomes a single
bg-[image:url(…),linear-gradient(…)]utility; theimage:data-type hint is required, because Tailwind would otherwise read the value as a colour. bg-cover bg-center bg-no-repeatreplaces three declarations that the CSS version repeats per card.motion-reduce:opacity-50instead of the CSS version's 0.5: same value, but stated on the element next to the animated one, so the two cannot drift.- The stylesheet holds only the root rule and
::selection. The blend mode, the isolation and the layered background all had utility forms.
Here's a working CSS demo from CodeFronts. Use it as-is or adapt to your framework. All classes are scoped under a unique prefix so the code won't collide with your existing styles. MIT licensed.
Demo: Tailwind Image Color Overlay Tint on Hover
Source: https://codefronts.com/motion/tailwind-css-image-hover-effects/tailwind-image-color-overlay-tint-on-hover/
A brand colour washed over a photograph with mix-blend-color, which replaces hue and saturation while keeping luminosity — a lighting gel, not a paint bucket. The tint is a per-card inline custom property, so the overlay is one class list serving any colour, and the text sits in an isolate wrapper so the blend cannot touch it.
## HTML
```html
<section class="tih-07 w-full min-h-svh grid place-items-center bg-tih07-bg font-tih07-sans px-6 py-10" aria-label="Colour overlay tint on hover demo">
<div class="grid w-full max-w-195 gap-4 grid-cols-1 sm:grid-cols-3">
<article style="--tint:oklch(0.7 0.19 45)" class="group relative overflow-hidden rounded-[14px] aspect-square">
<div class="absolute inset-0 grid place-items-center bg-[image:url('https://picsum.photos/seed/landscape-orange/600/600'),linear-gradient(135deg,oklch(0.27_0.03_265),oklch(0.35_0.02_265),oklch(0.45_0.015_265))] bg-cover bg-center bg-no-repeat transition-transform duration-380 ease-tih07 group-hover:scale-106 motion-reduce:transition-none motion-reduce:group-hover:scale-100">
</div>
<div class="absolute inset-0 bg-[var(--tint)] mix-blend-color opacity-0 transition-opacity duration-380 ease-tih07 group-hover:opacity-70 motion-reduce:transition-none motion-reduce:opacity-50"></div>
<span class="absolute top-2.5 left-2.5 z-2 isolate px-2 py-0.75 rounded-md text-[10px] font-semibold text-tih07-muted bg-[oklch(1_0_0/0.08)] border border-[oklch(1_0_0/0.1)]">Brand A</span>
<div class="absolute inset-0 z-2 isolate grid place-items-center">
<p class="text-sm font-bold text-tih07-text opacity-0 scale-90 transition-[opacity,scale] duration-380 ease-tih07 group-hover:opacity-100 group-hover:scale-100 motion-reduce:transition-none motion-reduce:opacity-100 motion-reduce:scale-100">Ember Orange Tint</p>
</div>
</article>
<article style="--tint:oklch(0.62 0.19 255)" class="group relative overflow-hidden rounded-[14px] aspect-square">
<div class="absolute inset-0 grid place-items-center bg-[image:url('https://picsum.photos/seed/landscape-blue/600/600'),linear-gradient(135deg,oklch(0.14_0_0),oklch(0.22_0_0),oklch(0.3_0_0))] bg-cover bg-center bg-no-repeat transition-transform duration-380 ease-tih07 group-hover:scale-106 motion-reduce:transition-none motion-reduce:group-hover:scale-100">
</div>
<div class="absolute inset-0 bg-[var(--tint)] mix-blend-color opacity-0 transition-opacity duration-380 ease-tih07 group-hover:opacity-70 motion-reduce:transition-none motion-reduce:opacity-50"></div>
<span class="absolute top-2.5 left-2.5 z-2 isolate px-2 py-0.75 rounded-md text-[10px] font-semibold text-tih07-muted bg-[oklch(1_0_0/0.08)] border border-[oklch(1_0_0/0.1)]">Brand B</span>
<div class="absolute inset-0 z-2 isolate grid place-items-center">
<p class="text-sm font-bold text-tih07-text opacity-0 scale-90 transition-[opacity,scale] duration-380 ease-tih07 group-hover:opacity-100 group-hover:scale-100 motion-reduce:transition-none motion-reduce:opacity-100 motion-reduce:scale-100">Pacific Blue Tint</p>
</div>
</article>
<article style="--tint:oklch(0.62 0.21 295)" class="group relative overflow-hidden rounded-[14px] aspect-square">
<div class="absolute inset-0 grid place-items-center bg-[image:url('https://picsum.photos/seed/landscape-violet/600/600'),linear-gradient(135deg,oklch(0.16_0.01_285),oklch(0.21_0.015_285),oklch(0.29_0.02_285))] bg-cover bg-center bg-no-repeat transition-transform duration-380 ease-tih07 group-hover:scale-106 motion-reduce:transition-none motion-reduce:group-hover:scale-100">
</div>
<div class="absolute inset-0 bg-[var(--tint)] mix-blend-color opacity-0 transition-opacity duration-380 ease-tih07 group-hover:opacity-70 motion-reduce:transition-none motion-reduce:opacity-50"></div>
<span class="absolute top-2.5 left-2.5 z-2 isolate px-2 py-0.75 rounded-md text-[10px] font-semibold text-tih07-muted bg-[oklch(1_0_0/0.08)] border border-[oklch(1_0_0/0.1)]">Brand C</span>
<div class="absolute inset-0 z-2 isolate grid place-items-center">
<p class="text-sm font-bold text-tih07-text opacity-0 scale-90 transition-[opacity,scale] duration-380 ease-tih07 group-hover:opacity-100 group-hover:scale-100 motion-reduce:transition-none motion-reduce:opacity-100 motion-reduce:scale-100">Deep Violet Tint</p>
</div>
</article>
</div>
</section>
```
## CSS
```css
@import "tailwindcss";
@theme {
--color-tih07-bg: #0d0d0f;
--color-tih07-bg: oklch(0.15 0.004 285);
--color-tih07-text: #f1f5f9;
--color-tih07-text: oklch(0.96 0.005 250);
--color-tih07-muted: #94a3b8;
--color-tih07-muted: oklch(0.7 0.03 250);
--color-tih07-acc: #f97316;
--color-tih07-acc: oklch(0.7 0.19 45);
--font-tih07-sans: 'Space Grotesk', system-ui, sans-serif;
--ease-tih07: cubic-bezier(0.25, 0.46, 0.45, 0.94);
}
/* Root rule: the full-bleed contract, stated in CSS as well as in the markup's
w-full min-h-svh, so the stage is correctly sized before the browser build compiles. */
.tih-07 {
width: 100%;
min-height: 100svh;
}
.tih-07 ::selection {
background: oklch(0.7 0.19 45);
color: #000;
}
```Here's a working CSS demo from CodeFronts. Use it as-is or adapt to your framework. All classes are scoped under a unique prefix so the code won't collide with your existing styles. MIT licensed.
Demo: Tailwind Image Color Overlay Tint on Hover
Source: https://codefronts.com/motion/tailwind-css-image-hover-effects/tailwind-image-color-overlay-tint-on-hover/
A brand colour washed over a photograph with mix-blend-color, which replaces hue and saturation while keeping luminosity — a lighting gel, not a paint bucket. The tint is a per-card inline custom property, so the overlay is one class list serving any colour, and the text sits in an isolate wrapper so the blend cannot touch it.
## HTML
```html
<section class="tih-07 w-full min-h-svh grid place-items-center bg-tih07-bg font-tih07-sans px-6 py-10" aria-label="Colour overlay tint on hover demo">
<div class="grid w-full max-w-195 gap-4 grid-cols-1 sm:grid-cols-3">
<article style="--tint:oklch(0.7 0.19 45)" class="group relative overflow-hidden rounded-[14px] aspect-square">
<div class="absolute inset-0 grid place-items-center bg-[image:url('https://picsum.photos/seed/landscape-orange/600/600'),linear-gradient(135deg,oklch(0.27_0.03_265),oklch(0.35_0.02_265),oklch(0.45_0.015_265))] bg-cover bg-center bg-no-repeat transition-transform duration-380 ease-tih07 group-hover:scale-106 motion-reduce:transition-none motion-reduce:group-hover:scale-100">
</div>
<div class="absolute inset-0 bg-[var(--tint)] mix-blend-color opacity-0 transition-opacity duration-380 ease-tih07 group-hover:opacity-70 motion-reduce:transition-none motion-reduce:opacity-50"></div>
<span class="absolute top-2.5 left-2.5 z-2 isolate px-2 py-0.75 rounded-md text-[10px] font-semibold text-tih07-muted bg-[oklch(1_0_0/0.08)] border border-[oklch(1_0_0/0.1)]">Brand A</span>
<div class="absolute inset-0 z-2 isolate grid place-items-center">
<p class="text-sm font-bold text-tih07-text opacity-0 scale-90 transition-[opacity,scale] duration-380 ease-tih07 group-hover:opacity-100 group-hover:scale-100 motion-reduce:transition-none motion-reduce:opacity-100 motion-reduce:scale-100">Ember Orange Tint</p>
</div>
</article>
<article style="--tint:oklch(0.62 0.19 255)" class="group relative overflow-hidden rounded-[14px] aspect-square">
<div class="absolute inset-0 grid place-items-center bg-[image:url('https://picsum.photos/seed/landscape-blue/600/600'),linear-gradient(135deg,oklch(0.14_0_0),oklch(0.22_0_0),oklch(0.3_0_0))] bg-cover bg-center bg-no-repeat transition-transform duration-380 ease-tih07 group-hover:scale-106 motion-reduce:transition-none motion-reduce:group-hover:scale-100">
</div>
<div class="absolute inset-0 bg-[var(--tint)] mix-blend-color opacity-0 transition-opacity duration-380 ease-tih07 group-hover:opacity-70 motion-reduce:transition-none motion-reduce:opacity-50"></div>
<span class="absolute top-2.5 left-2.5 z-2 isolate px-2 py-0.75 rounded-md text-[10px] font-semibold text-tih07-muted bg-[oklch(1_0_0/0.08)] border border-[oklch(1_0_0/0.1)]">Brand B</span>
<div class="absolute inset-0 z-2 isolate grid place-items-center">
<p class="text-sm font-bold text-tih07-text opacity-0 scale-90 transition-[opacity,scale] duration-380 ease-tih07 group-hover:opacity-100 group-hover:scale-100 motion-reduce:transition-none motion-reduce:opacity-100 motion-reduce:scale-100">Pacific Blue Tint</p>
</div>
</article>
<article style="--tint:oklch(0.62 0.21 295)" class="group relative overflow-hidden rounded-[14px] aspect-square">
<div class="absolute inset-0 grid place-items-center bg-[image:url('https://picsum.photos/seed/landscape-violet/600/600'),linear-gradient(135deg,oklch(0.16_0.01_285),oklch(0.21_0.015_285),oklch(0.29_0.02_285))] bg-cover bg-center bg-no-repeat transition-transform duration-380 ease-tih07 group-hover:scale-106 motion-reduce:transition-none motion-reduce:group-hover:scale-100">
</div>
<div class="absolute inset-0 bg-[var(--tint)] mix-blend-color opacity-0 transition-opacity duration-380 ease-tih07 group-hover:opacity-70 motion-reduce:transition-none motion-reduce:opacity-50"></div>
<span class="absolute top-2.5 left-2.5 z-2 isolate px-2 py-0.75 rounded-md text-[10px] font-semibold text-tih07-muted bg-[oklch(1_0_0/0.08)] border border-[oklch(1_0_0/0.1)]">Brand C</span>
<div class="absolute inset-0 z-2 isolate grid place-items-center">
<p class="text-sm font-bold text-tih07-text opacity-0 scale-90 transition-[opacity,scale] duration-380 ease-tih07 group-hover:opacity-100 group-hover:scale-100 motion-reduce:transition-none motion-reduce:opacity-100 motion-reduce:scale-100">Deep Violet Tint</p>
</div>
</article>
</div>
</section>
```
## CSS
```css
@import "tailwindcss";
@theme {
--color-tih07-bg: #0d0d0f;
--color-tih07-bg: oklch(0.15 0.004 285);
--color-tih07-text: #f1f5f9;
--color-tih07-text: oklch(0.96 0.005 250);
--color-tih07-muted: #94a3b8;
--color-tih07-muted: oklch(0.7 0.03 250);
--color-tih07-acc: #f97316;
--color-tih07-acc: oklch(0.7 0.19 45);
--font-tih07-sans: 'Space Grotesk', system-ui, sans-serif;
--ease-tih07: cubic-bezier(0.25, 0.46, 0.45, 0.94);
}
/* Root rule: the full-bleed contract, stated in CSS as well as in the markup's
w-full min-h-svh, so the stage is correctly sized before the browser build compiles. */
.tih-07 {
width: 100%;
min-height: 100svh;
}
.tih-07 ::selection {
background: oklch(0.7 0.19 45);
color: #000;
}
```How this works
The blend mode is a utility; the colour is data.
<div style="--tint:oklch(0.7 0.19 45)">
<div class="absolute inset-0 bg-[var(--tint)] mix-blend-color
opacity-0 transition-opacity group-hover:opacity-70">A CMS can set --tint per record and the compiled CSS never changes — which is the important property, because a class name assembled at runtime compiles to nothing at all.
Isolation is the fix for blend bleed. mix-blend-mode blends against everything in its stacking context, so a label painted above the tint gets colour-shifted too. isolate on the label wrapper creates a new context and ends the problem in one utility — better than the CSS collection's advice to keep the text out of the overlay's subtree, because now it does not matter where it sits.
Photo plus fallback in one utility. bg-[image:url(…),linear-gradient(…)] layers the photograph over a gradient, so an unreachable CDN degrades to a tinted gradient rather than a black hole.
Make it yours
- Blend character:
mix-blend-multiplyfor ink-wash,mix-blend-screenfor overexposed,mix-blend-hueto shift hue only. - Wash strength:
group-hover:opacity-70→opacity-40keeps the photograph legible at all times. - Per-card colour: edit the inline
--tint. No new class, no new rule. - Two stacked tints with different blend modes and different
duration-*values give a chromatic drift on hover. - Swap the placeholder photos by replacing the
url(…)insidebg-[image:…]; keep the gradient behind it as the fallback.
Gotchas — read before shipping
mix-blend-modecreates a new stacking context and blends against its whole parent context — alwaysisolateanything that must stay true to colour.- The tint layer must sit above the photo and below the label. Utilities make z-order cheap to state; state it explicitly rather than relying on document order.
- Keep the text out of the blended subtree and isolate it. Either alone fails in one engine or another.
- Safari and Chrome resolve
mix-blend-colorover gradients slightly differently — test with your actual brand colours, not with a grey. bg-[var(--tint)]is only static-analysable because the class is literal.bg-[--tint]withoutvar()does not compile in v4.- The browser CDN build compiles in the page and is for prototyping only. Ship the CLI or a plugin build.
Browser support
| Chrome | Safari | Firefox | Edge |
|---|---|---|---|
| 111+ | 16.4+ | 128+ | 111+ |
mix-blend-mode is Chrome 41+, Safari 8+ and Firefox 32+; rendering differs slightly across engines because of colour-space handling.