13 / 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 Shining Light Glare Image Hover
A bright band swept across the artwork by a single pseudo-element — and in utilities the entire sweep is an after: chain on the frame: after:[translate:-200%] group-hover:after:[translate:300%]. No extra markup, no separate rule block, and the two ends of the travel sit next to each other.
Untitled UI Pro: 5,000+ React + Tailwind CSS v4 components · from $349 one-time
Untitled UI React · Affiliate link
The code
<section class="tih-13 w-full min-h-svh grid place-items-center bg-tih13-bg font-tih13-sans px-6 py-10" aria-label="Shining light glare image hover demo">
<div class="grid w-full max-w-195 gap-4 grid-cols-1 sm:grid-cols-3">
<article class="group relative overflow-hidden rounded-[14px] border border-[oklch(1_0_0/0.06)] transition-[border-color,box-shadow] duration-600 ease-tih13 hover:border-[oklch(0.84_0.16_85/0.3)] hover:shadow-[0_8px_40px_oklch(0.84_0.16_85/0.12)] motion-reduce:transition-none">
<div class="relative aspect-[4/3] grid place-items-center overflow-hidden bg-[image:url('https://picsum.photos/seed/tih13-gold/800/600'),linear-gradient(135deg,oklch(0.18_0.03_60),oklch(0.32_0.08_55),oklch(0.55_0.13_65),oklch(0.84_0.16_85))] bg-cover bg-center bg-no-repeat after:content-[''] after:absolute after:-inset-1/2 after:w-2/5 after:h-[200%] after:bg-linear-[105deg,transparent_40%,oklch(1_0_0/0.08)_45%,oklch(1_0_0/0.22)_50%,oklch(1_0_0/0.08)_55%,transparent_60%] after:skew-x-[-10deg] after:[translate:-200%] after:transition-[translate] after:duration-600 after:ease-tih13 group-hover:after:[translate:300%] motion-reduce:after:hidden">
</div>
<div class="px-4 py-3.5 bg-[oklch(0_0_0/0.4)]">
<p class="mb-1.25 text-[9px] font-bold tracking-[0.12em] uppercase text-tih13-acc">Premium</p>
<h3 class="text-sm font-bold text-tih13-text">Gold Tier Membership</h3>
<p class="mt-0.5 text-[11px] tracking-[-1px] text-tih13-acc" aria-label="Rated 5 out of 5">★★★★★</p>
<p class="mt-1.5 text-base font-extrabold text-tih13-acc tabular-nums">$49 / mo</p>
</div>
</article>
<article class="group relative overflow-hidden rounded-[14px] border border-[oklch(1_0_0/0.06)] transition-[border-color,box-shadow] duration-600 ease-tih13 hover:border-[oklch(0.84_0.16_85/0.3)] hover:shadow-[0_8px_40px_oklch(0.84_0.16_85/0.12)] motion-reduce:transition-none">
<div class="relative aspect-[4/3] grid place-items-center overflow-hidden bg-[image:url('https://picsum.photos/seed/tih13-platinum/800/600'),linear-gradient(135deg,oklch(0.15_0_0),oklch(0.25_0_0),oklch(0.4_0_0),oklch(0.72_0_0))] bg-cover bg-center bg-no-repeat after:content-[''] after:absolute after:-inset-1/2 after:w-2/5 after:h-[200%] after:bg-linear-[105deg,transparent_40%,oklch(1_0_0/0.08)_45%,oklch(1_0_0/0.22)_50%,oklch(1_0_0/0.08)_55%,transparent_60%] after:skew-x-[-10deg] after:[translate:-200%] after:transition-[translate] after:duration-600 after:ease-tih13 group-hover:after:[translate:300%] motion-reduce:after:hidden">
</div>
<div class="px-4 py-3.5 bg-[oklch(0_0_0/0.4)]">
<p class="mb-1.25 text-[9px] font-bold tracking-[0.12em] uppercase text-tih13-acc">Exclusive</p>
<h3 class="text-sm font-bold text-tih13-text">Platinum Credit Card</h3>
<p class="mt-0.5 text-[11px] tracking-[-1px] text-tih13-acc" aria-label="Rated 5 out of 5">★★★★★</p>
<p class="mt-1.5 text-base font-extrabold text-tih13-acc tabular-nums">0% APR 18mo</p>
</div>
</article>
<article class="group relative overflow-hidden rounded-[14px] border border-[oklch(1_0_0/0.06)] transition-[border-color,box-shadow] duration-600 ease-tih13 hover:border-[oklch(0.84_0.16_85/0.3)] hover:shadow-[0_8px_40px_oklch(0.84_0.16_85/0.12)] motion-reduce:transition-none">
<div class="relative aspect-[4/3] grid place-items-center overflow-hidden bg-[image:url('https://picsum.photos/seed/tih13-diamond/800/600'),linear-gradient(135deg,oklch(0.17_0.07_310),oklch(0.35_0.18_295),oklch(0.55_0.24_295),oklch(0.83_0.1_295))] bg-cover bg-center bg-no-repeat after:content-[''] after:absolute after:-inset-1/2 after:w-2/5 after:h-[200%] after:bg-linear-[105deg,transparent_40%,oklch(1_0_0/0.08)_45%,oklch(1_0_0/0.22)_50%,oklch(1_0_0/0.08)_55%,transparent_60%] after:skew-x-[-10deg] after:[translate:-200%] after:transition-[translate] after:duration-600 after:ease-tih13 group-hover:after:[translate:300%] motion-reduce:after:hidden">
</div>
<div class="px-4 py-3.5 bg-[oklch(0_0_0/0.4)]">
<p class="mb-1.25 text-[9px] font-bold tracking-[0.12em] uppercase text-tih13-acc">Diamond</p>
<h3 class="text-sm font-bold text-tih13-text">Crystal Pro Bundle</h3>
<p class="mt-0.5 text-[11px] tracking-[-1px] text-tih13-acc" aria-label="Rated 5 out of 5">★★★★★</p>
<p class="mt-1.5 text-base font-extrabold text-tih13-acc tabular-nums">$299 / yr</p>
</div>
</article>
</div>
</section><section class="tih-13 w-full min-h-svh grid place-items-center bg-tih13-bg font-tih13-sans px-6 py-10" aria-label="Shining light glare image hover demo">
<div class="grid w-full max-w-195 gap-4 grid-cols-1 sm:grid-cols-3">
<article class="group relative overflow-hidden rounded-[14px] border border-[oklch(1_0_0/0.06)] transition-[border-color,box-shadow] duration-600 ease-tih13 hover:border-[oklch(0.84_0.16_85/0.3)] hover:shadow-[0_8px_40px_oklch(0.84_0.16_85/0.12)] motion-reduce:transition-none">
<div class="relative aspect-[4/3] grid place-items-center overflow-hidden bg-[image:url('https://picsum.photos/seed/tih13-gold/800/600'),linear-gradient(135deg,oklch(0.18_0.03_60),oklch(0.32_0.08_55),oklch(0.55_0.13_65),oklch(0.84_0.16_85))] bg-cover bg-center bg-no-repeat after:content-[''] after:absolute after:-inset-1/2 after:w-2/5 after:h-[200%] after:bg-linear-[105deg,transparent_40%,oklch(1_0_0/0.08)_45%,oklch(1_0_0/0.22)_50%,oklch(1_0_0/0.08)_55%,transparent_60%] after:skew-x-[-10deg] after:[translate:-200%] after:transition-[translate] after:duration-600 after:ease-tih13 group-hover:after:[translate:300%] motion-reduce:after:hidden">
</div>
<div class="px-4 py-3.5 bg-[oklch(0_0_0/0.4)]">
<p class="mb-1.25 text-[9px] font-bold tracking-[0.12em] uppercase text-tih13-acc">Premium</p>
<h3 class="text-sm font-bold text-tih13-text">Gold Tier Membership</h3>
<p class="mt-0.5 text-[11px] tracking-[-1px] text-tih13-acc" aria-label="Rated 5 out of 5">★★★★★</p>
<p class="mt-1.5 text-base font-extrabold text-tih13-acc tabular-nums">$49 / mo</p>
</div>
</article>
<article class="group relative overflow-hidden rounded-[14px] border border-[oklch(1_0_0/0.06)] transition-[border-color,box-shadow] duration-600 ease-tih13 hover:border-[oklch(0.84_0.16_85/0.3)] hover:shadow-[0_8px_40px_oklch(0.84_0.16_85/0.12)] motion-reduce:transition-none">
<div class="relative aspect-[4/3] grid place-items-center overflow-hidden bg-[image:url('https://picsum.photos/seed/tih13-platinum/800/600'),linear-gradient(135deg,oklch(0.15_0_0),oklch(0.25_0_0),oklch(0.4_0_0),oklch(0.72_0_0))] bg-cover bg-center bg-no-repeat after:content-[''] after:absolute after:-inset-1/2 after:w-2/5 after:h-[200%] after:bg-linear-[105deg,transparent_40%,oklch(1_0_0/0.08)_45%,oklch(1_0_0/0.22)_50%,oklch(1_0_0/0.08)_55%,transparent_60%] after:skew-x-[-10deg] after:[translate:-200%] after:transition-[translate] after:duration-600 after:ease-tih13 group-hover:after:[translate:300%] motion-reduce:after:hidden">
</div>
<div class="px-4 py-3.5 bg-[oklch(0_0_0/0.4)]">
<p class="mb-1.25 text-[9px] font-bold tracking-[0.12em] uppercase text-tih13-acc">Exclusive</p>
<h3 class="text-sm font-bold text-tih13-text">Platinum Credit Card</h3>
<p class="mt-0.5 text-[11px] tracking-[-1px] text-tih13-acc" aria-label="Rated 5 out of 5">★★★★★</p>
<p class="mt-1.5 text-base font-extrabold text-tih13-acc tabular-nums">0% APR 18mo</p>
</div>
</article>
<article class="group relative overflow-hidden rounded-[14px] border border-[oklch(1_0_0/0.06)] transition-[border-color,box-shadow] duration-600 ease-tih13 hover:border-[oklch(0.84_0.16_85/0.3)] hover:shadow-[0_8px_40px_oklch(0.84_0.16_85/0.12)] motion-reduce:transition-none">
<div class="relative aspect-[4/3] grid place-items-center overflow-hidden bg-[image:url('https://picsum.photos/seed/tih13-diamond/800/600'),linear-gradient(135deg,oklch(0.17_0.07_310),oklch(0.35_0.18_295),oklch(0.55_0.24_295),oklch(0.83_0.1_295))] bg-cover bg-center bg-no-repeat after:content-[''] after:absolute after:-inset-1/2 after:w-2/5 after:h-[200%] after:bg-linear-[105deg,transparent_40%,oklch(1_0_0/0.08)_45%,oklch(1_0_0/0.22)_50%,oklch(1_0_0/0.08)_55%,transparent_60%] after:skew-x-[-10deg] after:[translate:-200%] after:transition-[translate] after:duration-600 after:ease-tih13 group-hover:after:[translate:300%] motion-reduce:after:hidden">
</div>
<div class="px-4 py-3.5 bg-[oklch(0_0_0/0.4)]">
<p class="mb-1.25 text-[9px] font-bold tracking-[0.12em] uppercase text-tih13-acc">Diamond</p>
<h3 class="text-sm font-bold text-tih13-text">Crystal Pro Bundle</h3>
<p class="mt-0.5 text-[11px] tracking-[-1px] text-tih13-acc" aria-label="Rated 5 out of 5">★★★★★</p>
<p class="mt-1.5 text-base font-extrabold text-tih13-acc tabular-nums">$299 / yr</p>
</div>
</article>
</div>
</section>@import "tailwindcss";
@theme {
--color-tih13-bg: #0a0906;
--color-tih13-bg: oklch(0.12 0.008 85);
--color-tih13-text: #f1f5f9;
--color-tih13-text: oklch(0.96 0.005 250);
--color-tih13-muted: #78716c;
--color-tih13-muted: oklch(0.6 0.01 60);
--color-tih13-acc: #fbbf24;
--color-tih13-acc: oklch(0.84 0.16 85);
--font-tih13-sans: 'Space Grotesk', system-ui, sans-serif;
--ease-tih13: cubic-bezier(0.4, 0, 0.2, 1);
}
/* 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-13 {
width: 100%;
min-height: 100svh;
}
.tih-13 ::selection {
background: oklch(0.84 0.16 85);
color: #000;
}@import "tailwindcss";
@theme {
--color-tih13-bg: #0a0906;
--color-tih13-bg: oklch(0.12 0.008 85);
--color-tih13-text: #f1f5f9;
--color-tih13-text: oklch(0.96 0.005 250);
--color-tih13-muted: #78716c;
--color-tih13-muted: oklch(0.6 0.01 60);
--color-tih13-acc: #fbbf24;
--color-tih13-acc: oklch(0.84 0.16 85);
--font-tih13-sans: 'Space Grotesk', system-ui, sans-serif;
--ease-tih13: cubic-bezier(0.4, 0, 0.2, 1);
}
/* 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-13 {
width: 100%;
min-height: 100svh;
}
.tih-13 ::selection {
background: oklch(0.84 0.16 85);
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-tih13-bg: #0a0906;
--color-tih13-bg: oklch(0.12 0.008 85);
--color-tih13-text: #f1f5f9;
--color-tih13-text: oklch(0.96 0.005 250);
--color-tih13-muted: #78716c;
--color-tih13-muted: oklch(0.6 0.01 60);
--color-tih13-acc: #fbbf24;
--color-tih13-acc: oklch(0.84 0.16 85);
--font-tih13-sans: 'Space Grotesk', system-ui, sans-serif;
--ease-tih13: cubic-bezier(0.4, 0, 0.2, 1);
}
/* 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-13 {
width: 100%;
min-height: 100svh;
}
.tih-13 ::selection {
background: oklch(0.84 0.16 85);
color: #000;
}@import "tailwindcss";
@theme {
--color-tih13-bg: #0a0906;
--color-tih13-bg: oklch(0.12 0.008 85);
--color-tih13-text: #f1f5f9;
--color-tih13-text: oklch(0.96 0.005 250);
--color-tih13-muted: #78716c;
--color-tih13-muted: oklch(0.6 0.01 60);
--color-tih13-acc: #fbbf24;
--color-tih13-acc: oklch(0.84 0.16 85);
--font-tih13-sans: 'Space Grotesk', system-ui, sans-serif;
--ease-tih13: cubic-bezier(0.4, 0, 0.2, 1);
}
/* 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-13 {
width: 100%;
min-height: 100svh;
}
.tih-13 ::selection {
background: oklch(0.84 0.16 85);
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.
- An entire
::afterrule plus its hover rule become oneafter:variant chain — eleven utilities, all on the element that owns the sheen. This is the collection's best case for pseudo-element variants. - The five-stop gradient stays one arbitrary value. Stops are a tuned curve, not tokens, and splitting them would make the band harder to read, not easier.
after:transition-[translate]rather thantransition-transform: the skew is a separate individual property now, and namingtransformwould animate nothing.after:-inset-1/2plusafter:w-2/5 after:h-[200%]replaces four declarations, and the oversize box is now visibly intentional rather than a magicinset:-50%.motion-reduce:after:hiddenmatches the CSS version'sdisplay:noneexactly, in one utility, with no repeated selector.- The class list is long — honestly long. This is the demo where a component wrapper (not
@apply) is the right answer in a real codebase.
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 Shining Light Glare Image Hover
Source: https://codefronts.com/motion/tailwind-css-image-hover-effects/tailwind-shining-light-glare-image-hover/
A bright band swept across the artwork by a single pseudo-element — and in utilities the entire sweep is an after: chain on the frame: after:[translate:-200%] group-hover:after:[translate:300%]. No extra markup, no separate rule block, and the two ends of the travel sit next to each other.
## HTML
```html
<section class="tih-13 w-full min-h-svh grid place-items-center bg-tih13-bg font-tih13-sans px-6 py-10" aria-label="Shining light glare image hover demo">
<div class="grid w-full max-w-195 gap-4 grid-cols-1 sm:grid-cols-3">
<article class="group relative overflow-hidden rounded-[14px] border border-[oklch(1_0_0/0.06)] transition-[border-color,box-shadow] duration-600 ease-tih13 hover:border-[oklch(0.84_0.16_85/0.3)] hover:shadow-[0_8px_40px_oklch(0.84_0.16_85/0.12)] motion-reduce:transition-none">
<div class="relative aspect-[4/3] grid place-items-center overflow-hidden bg-[image:url('https://picsum.photos/seed/tih13-gold/800/600'),linear-gradient(135deg,oklch(0.18_0.03_60),oklch(0.32_0.08_55),oklch(0.55_0.13_65),oklch(0.84_0.16_85))] bg-cover bg-center bg-no-repeat after:content-[''] after:absolute after:-inset-1/2 after:w-2/5 after:h-[200%] after:bg-linear-[105deg,transparent_40%,oklch(1_0_0/0.08)_45%,oklch(1_0_0/0.22)_50%,oklch(1_0_0/0.08)_55%,transparent_60%] after:skew-x-[-10deg] after:[translate:-200%] after:transition-[translate] after:duration-600 after:ease-tih13 group-hover:after:[translate:300%] motion-reduce:after:hidden">
</div>
<div class="px-4 py-3.5 bg-[oklch(0_0_0/0.4)]">
<p class="mb-1.25 text-[9px] font-bold tracking-[0.12em] uppercase text-tih13-acc">Premium</p>
<h3 class="text-sm font-bold text-tih13-text">Gold Tier Membership</h3>
<p class="mt-0.5 text-[11px] tracking-[-1px] text-tih13-acc" aria-label="Rated 5 out of 5">★★★★★</p>
<p class="mt-1.5 text-base font-extrabold text-tih13-acc tabular-nums">$49 / mo</p>
</div>
</article>
<article class="group relative overflow-hidden rounded-[14px] border border-[oklch(1_0_0/0.06)] transition-[border-color,box-shadow] duration-600 ease-tih13 hover:border-[oklch(0.84_0.16_85/0.3)] hover:shadow-[0_8px_40px_oklch(0.84_0.16_85/0.12)] motion-reduce:transition-none">
<div class="relative aspect-[4/3] grid place-items-center overflow-hidden bg-[image:url('https://picsum.photos/seed/tih13-platinum/800/600'),linear-gradient(135deg,oklch(0.15_0_0),oklch(0.25_0_0),oklch(0.4_0_0),oklch(0.72_0_0))] bg-cover bg-center bg-no-repeat after:content-[''] after:absolute after:-inset-1/2 after:w-2/5 after:h-[200%] after:bg-linear-[105deg,transparent_40%,oklch(1_0_0/0.08)_45%,oklch(1_0_0/0.22)_50%,oklch(1_0_0/0.08)_55%,transparent_60%] after:skew-x-[-10deg] after:[translate:-200%] after:transition-[translate] after:duration-600 after:ease-tih13 group-hover:after:[translate:300%] motion-reduce:after:hidden">
</div>
<div class="px-4 py-3.5 bg-[oklch(0_0_0/0.4)]">
<p class="mb-1.25 text-[9px] font-bold tracking-[0.12em] uppercase text-tih13-acc">Exclusive</p>
<h3 class="text-sm font-bold text-tih13-text">Platinum Credit Card</h3>
<p class="mt-0.5 text-[11px] tracking-[-1px] text-tih13-acc" aria-label="Rated 5 out of 5">★★★★★</p>
<p class="mt-1.5 text-base font-extrabold text-tih13-acc tabular-nums">0% APR 18mo</p>
</div>
</article>
<article class="group relative overflow-hidden rounded-[14px] border border-[oklch(1_0_0/0.06)] transition-[border-color,box-shadow] duration-600 ease-tih13 hover:border-[oklch(0.84_0.16_85/0.3)] hover:shadow-[0_8px_40px_oklch(0.84_0.16_85/0.12)] motion-reduce:transition-none">
<div class="relative aspect-[4/3] grid place-items-center overflow-hidden bg-[image:url('https://picsum.photos/seed/tih13-diamond/800/600'),linear-gradient(135deg,oklch(0.17_0.07_310),oklch(0.35_0.18_295),oklch(0.55_0.24_295),oklch(0.83_0.1_295))] bg-cover bg-center bg-no-repeat after:content-[''] after:absolute after:-inset-1/2 after:w-2/5 after:h-[200%] after:bg-linear-[105deg,transparent_40%,oklch(1_0_0/0.08)_45%,oklch(1_0_0/0.22)_50%,oklch(1_0_0/0.08)_55%,transparent_60%] after:skew-x-[-10deg] after:[translate:-200%] after:transition-[translate] after:duration-600 after:ease-tih13 group-hover:after:[translate:300%] motion-reduce:after:hidden">
</div>
<div class="px-4 py-3.5 bg-[oklch(0_0_0/0.4)]">
<p class="mb-1.25 text-[9px] font-bold tracking-[0.12em] uppercase text-tih13-acc">Diamond</p>
<h3 class="text-sm font-bold text-tih13-text">Crystal Pro Bundle</h3>
<p class="mt-0.5 text-[11px] tracking-[-1px] text-tih13-acc" aria-label="Rated 5 out of 5">★★★★★</p>
<p class="mt-1.5 text-base font-extrabold text-tih13-acc tabular-nums">$299 / yr</p>
</div>
</article>
</div>
</section>
```
## CSS
```css
@import "tailwindcss";
@theme {
--color-tih13-bg: #0a0906;
--color-tih13-bg: oklch(0.12 0.008 85);
--color-tih13-text: #f1f5f9;
--color-tih13-text: oklch(0.96 0.005 250);
--color-tih13-muted: #78716c;
--color-tih13-muted: oklch(0.6 0.01 60);
--color-tih13-acc: #fbbf24;
--color-tih13-acc: oklch(0.84 0.16 85);
--font-tih13-sans: 'Space Grotesk', system-ui, sans-serif;
--ease-tih13: cubic-bezier(0.4, 0, 0.2, 1);
}
/* 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-13 {
width: 100%;
min-height: 100svh;
}
.tih-13 ::selection {
background: oklch(0.84 0.16 85);
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 Shining Light Glare Image Hover
Source: https://codefronts.com/motion/tailwind-css-image-hover-effects/tailwind-shining-light-glare-image-hover/
A bright band swept across the artwork by a single pseudo-element — and in utilities the entire sweep is an after: chain on the frame: after:[translate:-200%] group-hover:after:[translate:300%]. No extra markup, no separate rule block, and the two ends of the travel sit next to each other.
## HTML
```html
<section class="tih-13 w-full min-h-svh grid place-items-center bg-tih13-bg font-tih13-sans px-6 py-10" aria-label="Shining light glare image hover demo">
<div class="grid w-full max-w-195 gap-4 grid-cols-1 sm:grid-cols-3">
<article class="group relative overflow-hidden rounded-[14px] border border-[oklch(1_0_0/0.06)] transition-[border-color,box-shadow] duration-600 ease-tih13 hover:border-[oklch(0.84_0.16_85/0.3)] hover:shadow-[0_8px_40px_oklch(0.84_0.16_85/0.12)] motion-reduce:transition-none">
<div class="relative aspect-[4/3] grid place-items-center overflow-hidden bg-[image:url('https://picsum.photos/seed/tih13-gold/800/600'),linear-gradient(135deg,oklch(0.18_0.03_60),oklch(0.32_0.08_55),oklch(0.55_0.13_65),oklch(0.84_0.16_85))] bg-cover bg-center bg-no-repeat after:content-[''] after:absolute after:-inset-1/2 after:w-2/5 after:h-[200%] after:bg-linear-[105deg,transparent_40%,oklch(1_0_0/0.08)_45%,oklch(1_0_0/0.22)_50%,oklch(1_0_0/0.08)_55%,transparent_60%] after:skew-x-[-10deg] after:[translate:-200%] after:transition-[translate] after:duration-600 after:ease-tih13 group-hover:after:[translate:300%] motion-reduce:after:hidden">
</div>
<div class="px-4 py-3.5 bg-[oklch(0_0_0/0.4)]">
<p class="mb-1.25 text-[9px] font-bold tracking-[0.12em] uppercase text-tih13-acc">Premium</p>
<h3 class="text-sm font-bold text-tih13-text">Gold Tier Membership</h3>
<p class="mt-0.5 text-[11px] tracking-[-1px] text-tih13-acc" aria-label="Rated 5 out of 5">★★★★★</p>
<p class="mt-1.5 text-base font-extrabold text-tih13-acc tabular-nums">$49 / mo</p>
</div>
</article>
<article class="group relative overflow-hidden rounded-[14px] border border-[oklch(1_0_0/0.06)] transition-[border-color,box-shadow] duration-600 ease-tih13 hover:border-[oklch(0.84_0.16_85/0.3)] hover:shadow-[0_8px_40px_oklch(0.84_0.16_85/0.12)] motion-reduce:transition-none">
<div class="relative aspect-[4/3] grid place-items-center overflow-hidden bg-[image:url('https://picsum.photos/seed/tih13-platinum/800/600'),linear-gradient(135deg,oklch(0.15_0_0),oklch(0.25_0_0),oklch(0.4_0_0),oklch(0.72_0_0))] bg-cover bg-center bg-no-repeat after:content-[''] after:absolute after:-inset-1/2 after:w-2/5 after:h-[200%] after:bg-linear-[105deg,transparent_40%,oklch(1_0_0/0.08)_45%,oklch(1_0_0/0.22)_50%,oklch(1_0_0/0.08)_55%,transparent_60%] after:skew-x-[-10deg] after:[translate:-200%] after:transition-[translate] after:duration-600 after:ease-tih13 group-hover:after:[translate:300%] motion-reduce:after:hidden">
</div>
<div class="px-4 py-3.5 bg-[oklch(0_0_0/0.4)]">
<p class="mb-1.25 text-[9px] font-bold tracking-[0.12em] uppercase text-tih13-acc">Exclusive</p>
<h3 class="text-sm font-bold text-tih13-text">Platinum Credit Card</h3>
<p class="mt-0.5 text-[11px] tracking-[-1px] text-tih13-acc" aria-label="Rated 5 out of 5">★★★★★</p>
<p class="mt-1.5 text-base font-extrabold text-tih13-acc tabular-nums">0% APR 18mo</p>
</div>
</article>
<article class="group relative overflow-hidden rounded-[14px] border border-[oklch(1_0_0/0.06)] transition-[border-color,box-shadow] duration-600 ease-tih13 hover:border-[oklch(0.84_0.16_85/0.3)] hover:shadow-[0_8px_40px_oklch(0.84_0.16_85/0.12)] motion-reduce:transition-none">
<div class="relative aspect-[4/3] grid place-items-center overflow-hidden bg-[image:url('https://picsum.photos/seed/tih13-diamond/800/600'),linear-gradient(135deg,oklch(0.17_0.07_310),oklch(0.35_0.18_295),oklch(0.55_0.24_295),oklch(0.83_0.1_295))] bg-cover bg-center bg-no-repeat after:content-[''] after:absolute after:-inset-1/2 after:w-2/5 after:h-[200%] after:bg-linear-[105deg,transparent_40%,oklch(1_0_0/0.08)_45%,oklch(1_0_0/0.22)_50%,oklch(1_0_0/0.08)_55%,transparent_60%] after:skew-x-[-10deg] after:[translate:-200%] after:transition-[translate] after:duration-600 after:ease-tih13 group-hover:after:[translate:300%] motion-reduce:after:hidden">
</div>
<div class="px-4 py-3.5 bg-[oklch(0_0_0/0.4)]">
<p class="mb-1.25 text-[9px] font-bold tracking-[0.12em] uppercase text-tih13-acc">Diamond</p>
<h3 class="text-sm font-bold text-tih13-text">Crystal Pro Bundle</h3>
<p class="mt-0.5 text-[11px] tracking-[-1px] text-tih13-acc" aria-label="Rated 5 out of 5">★★★★★</p>
<p class="mt-1.5 text-base font-extrabold text-tih13-acc tabular-nums">$299 / yr</p>
</div>
</article>
</div>
</section>
```
## CSS
```css
@import "tailwindcss";
@theme {
--color-tih13-bg: #0a0906;
--color-tih13-bg: oklch(0.12 0.008 85);
--color-tih13-text: #f1f5f9;
--color-tih13-text: oklch(0.96 0.005 250);
--color-tih13-muted: #78716c;
--color-tih13-muted: oklch(0.6 0.01 60);
--color-tih13-acc: #fbbf24;
--color-tih13-acc: oklch(0.84 0.16 85);
--font-tih13-sans: 'Space Grotesk', system-ui, sans-serif;
--ease-tih13: cubic-bezier(0.4, 0, 0.2, 1);
}
/* 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-13 {
width: 100%;
min-height: 100svh;
}
.tih-13 ::selection {
background: oklch(0.84 0.16 85);
color: #000;
}
```How this works
The whole effect is one variant chain.
class="relative overflow-hidden
after:content-[''] after:absolute after:-inset-1/2 after:w-2/5 after:h-[200%]
after:bg-linear-[105deg,transparent_40%,…,transparent_60%]
after:skew-x-[-10deg] after:[translate:-200%]
after:transition-[translate] after:duration-600
group-hover:after:[translate:300%]"Tailwind's pseudo-element variants are what make this port worth doing: the sheen's size, gradient, tilt, resting position and travel are all on the element that owns it, in the order they matter.
Why transition, not animation. A transition restarts cleanly from the left on every re-hover; a keyframe animation needs retriggering gymnastics. The CSS version makes the same call, and the port keeps it.
Only translate animates. after:transition-[translate] means the gradient, the skew and the size never re-interpolate — the sweep is one compositor property moving.
Make it yours
- Band softness: widen the gradient stops from
40/50/60to30/50/70. - Cinematic pace:
after:duration-900 after:ease-in-out. - Always-on: add an
--animate-tih13-sweep@themeentry and swap the hover pair forafter:animate-tih13-sweep. - Dark artwork: raise the peak stop to
oklch(1_0_0/0.4). - Second softer layer: a
before:chain at 15% opacity and a longer duration gives a multi-layer flare.
Gotchas — read before shipping
after:content-['']is mandatory — without it nothing renders and the class list looks correct.- The frame needs
overflow-hiddenor the sheen sweeps out over the page. - Keep the sweep box oversized (
-inset-1/2,h-[200%]) so the band fully clears both edges; a tight box shows the band appearing mid-card. - Do not add a filter to the pseudo-element — it creates a stacking context on the parent and can reorder siblings.
- Negative arbitrary values go inside the brackets (
after:skew-x-[-10deg]), not as a leading minus on the variant. - 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+ |
Transforms on pseudo-elements need no prefixes in any modern engine; the sweep is removed automatically under prefers-reduced-motion.