14 / 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 Split Transition Hover
The card slices in half and an action strip wipes open in the gap. Two layers carry identical artwork and complementary clip-path polygons; the strip animates inset(100%_0_100%_0) to inset(0), so it opens from the centre line outward rather than fading in.
Untitled UI Pro: 5,000+ React + Tailwind CSS v4 components · from $349 one-time
Untitled UI React · Affiliate link
The code
<section class="tih-14 w-full min-h-svh grid place-items-center bg-tih14-bg font-tih14-sans px-6 py-10" aria-label="Image split transition hover demo">
<div class="grid w-full max-w-195 gap-5 grid-cols-1 sm:grid-cols-3">
<article class="group relative aspect-[3/4] rounded-[14px] overflow-hidden">
<div class="absolute inset-0 grid place-items-center bg-[image:url('https://picsum.photos/seed/tih14-canvas/600/800'),linear-gradient(135deg,oklch(0.17_0.07_310),oklch(0.35_0.18_298),oklch(0.55_0.24_295))] bg-cover bg-center bg-no-repeat [clip-path:polygon(0_0,100%_0,100%_50.5%,0_50.5%)] will-change-transform transition-[translate] duration-500 ease-tih14 group-hover:[translate:0_-6%] motion-reduce:transition-none motion-reduce:group-hover:[translate:0_0]">
</div>
<div class="absolute inset-0 grid place-items-center bg-[image:url('https://picsum.photos/seed/tih14-canvas/600/800'),linear-gradient(135deg,oklch(0.17_0.07_310),oklch(0.35_0.18_298),oklch(0.55_0.24_295))] bg-cover bg-center bg-no-repeat [clip-path:polygon(0_49.5%,100%_49.5%,100%_100%,0_100%)] will-change-transform transition-[translate] duration-500 ease-tih14 group-hover:[translate:0_6%] motion-reduce:transition-none motion-reduce:group-hover:[translate:0_0]">
</div>
<span class="absolute top-3 left-3 z-2 text-[22px] font-black leading-none text-[oklch(1_0_0/0.12)]" aria-hidden="true">01</span>
<div class="absolute inset-x-0 top-1/2 z-3 -translate-y-1/2 flex items-center justify-between px-4 py-3 bg-tih14-bg opacity-0 [clip-path:inset(100%_0_100%_0)] transition-[clip-path,opacity] duration-500 ease-tih14 group-hover:opacity-100 group-hover:[clip-path:inset(0)] focus-within:opacity-100 focus-within:[clip-path:inset(0)] motion-reduce:transition-none motion-reduce:opacity-100 motion-reduce:[clip-path:inset(0)]">
<p class="text-xs font-bold text-tih14-text">Digital Canvas</p>
<a href="#digital-canvas" class="px-2.5 py-1 rounded-full text-[10px] font-bold text-white bg-tih14-acc no-underline focus-visible:outline-2 focus-visible:outline-tih14-text focus-visible:outline-offset-2">View</a>
</div>
</article>
<article class="group relative aspect-[3/4] rounded-[14px] overflow-hidden">
<div class="absolute inset-0 grid place-items-center bg-[image:url('https://picsum.photos/seed/tih14-growth/600/800'),linear-gradient(135deg,oklch(0.25_0.05_180),oklch(0.42_0.09_165),oklch(0.7_0.15_163))] bg-cover bg-center bg-no-repeat [clip-path:polygon(0_0,100%_0,100%_50.5%,0_50.5%)] will-change-transform transition-[translate] duration-500 ease-tih14 group-hover:[translate:0_-6%] motion-reduce:transition-none motion-reduce:group-hover:[translate:0_0]">
</div>
<div class="absolute inset-0 grid place-items-center bg-[image:url('https://picsum.photos/seed/tih14-growth/600/800'),linear-gradient(135deg,oklch(0.25_0.05_180),oklch(0.42_0.09_165),oklch(0.7_0.15_163))] bg-cover bg-center bg-no-repeat [clip-path:polygon(0_49.5%,100%_49.5%,100%_100%,0_100%)] will-change-transform transition-[translate] duration-500 ease-tih14 group-hover:[translate:0_6%] motion-reduce:transition-none motion-reduce:group-hover:[translate:0_0]">
</div>
<span class="absolute top-3 left-3 z-2 text-[22px] font-black leading-none text-[oklch(1_0_0/0.12)]" aria-hidden="true">02</span>
<div class="absolute inset-x-0 top-1/2 z-3 -translate-y-1/2 flex items-center justify-between px-4 py-3 bg-tih14-bg opacity-0 [clip-path:inset(100%_0_100%_0)] transition-[clip-path,opacity] duration-500 ease-tih14 group-hover:opacity-100 group-hover:[clip-path:inset(0)] focus-within:opacity-100 focus-within:[clip-path:inset(0)] motion-reduce:transition-none motion-reduce:opacity-100 motion-reduce:[clip-path:inset(0)]">
<p class="text-xs font-bold text-tih14-text">Growth Series</p>
<a href="#growth-series" class="px-2.5 py-1 rounded-full text-[10px] font-bold text-white bg-tih14-acc no-underline focus-visible:outline-2 focus-visible:outline-tih14-text focus-visible:outline-offset-2">View</a>
</div>
</article>
<article class="group relative aspect-[3/4] rounded-[14px] overflow-hidden">
<div class="absolute inset-0 grid place-items-center bg-[image:url('https://picsum.photos/seed/tih14-power/600/800'),linear-gradient(135deg,oklch(0.18_0.03_60),oklch(0.45_0.11_60),oklch(0.78_0.16_72))] bg-cover bg-center bg-no-repeat [clip-path:polygon(0_0,100%_0,100%_50.5%,0_50.5%)] will-change-transform transition-[translate] duration-500 ease-tih14 group-hover:[translate:0_-6%] motion-reduce:transition-none motion-reduce:group-hover:[translate:0_0]">
</div>
<div class="absolute inset-0 grid place-items-center bg-[image:url('https://picsum.photos/seed/tih14-power/600/800'),linear-gradient(135deg,oklch(0.18_0.03_60),oklch(0.45_0.11_60),oklch(0.78_0.16_72))] bg-cover bg-center bg-no-repeat [clip-path:polygon(0_49.5%,100%_49.5%,100%_100%,0_100%)] will-change-transform transition-[translate] duration-500 ease-tih14 group-hover:[translate:0_6%] motion-reduce:transition-none motion-reduce:group-hover:[translate:0_0]">
</div>
<span class="absolute top-3 left-3 z-2 text-[22px] font-black leading-none text-[oklch(1_0_0/0.12)]" aria-hidden="true">03</span>
<div class="absolute inset-x-0 top-1/2 z-3 -translate-y-1/2 flex items-center justify-between px-4 py-3 bg-tih14-bg opacity-0 [clip-path:inset(100%_0_100%_0)] transition-[clip-path,opacity] duration-500 ease-tih14 group-hover:opacity-100 group-hover:[clip-path:inset(0)] focus-within:opacity-100 focus-within:[clip-path:inset(0)] motion-reduce:transition-none motion-reduce:opacity-100 motion-reduce:[clip-path:inset(0)]">
<p class="text-xs font-bold text-tih14-text">Power Study</p>
<a href="#power-study" class="px-2.5 py-1 rounded-full text-[10px] font-bold text-white bg-tih14-acc no-underline focus-visible:outline-2 focus-visible:outline-tih14-text focus-visible:outline-offset-2">View</a>
</div>
</article>
</div>
</section><section class="tih-14 w-full min-h-svh grid place-items-center bg-tih14-bg font-tih14-sans px-6 py-10" aria-label="Image split transition hover demo">
<div class="grid w-full max-w-195 gap-5 grid-cols-1 sm:grid-cols-3">
<article class="group relative aspect-[3/4] rounded-[14px] overflow-hidden">
<div class="absolute inset-0 grid place-items-center bg-[image:url('https://picsum.photos/seed/tih14-canvas/600/800'),linear-gradient(135deg,oklch(0.17_0.07_310),oklch(0.35_0.18_298),oklch(0.55_0.24_295))] bg-cover bg-center bg-no-repeat [clip-path:polygon(0_0,100%_0,100%_50.5%,0_50.5%)] will-change-transform transition-[translate] duration-500 ease-tih14 group-hover:[translate:0_-6%] motion-reduce:transition-none motion-reduce:group-hover:[translate:0_0]">
</div>
<div class="absolute inset-0 grid place-items-center bg-[image:url('https://picsum.photos/seed/tih14-canvas/600/800'),linear-gradient(135deg,oklch(0.17_0.07_310),oklch(0.35_0.18_298),oklch(0.55_0.24_295))] bg-cover bg-center bg-no-repeat [clip-path:polygon(0_49.5%,100%_49.5%,100%_100%,0_100%)] will-change-transform transition-[translate] duration-500 ease-tih14 group-hover:[translate:0_6%] motion-reduce:transition-none motion-reduce:group-hover:[translate:0_0]">
</div>
<span class="absolute top-3 left-3 z-2 text-[22px] font-black leading-none text-[oklch(1_0_0/0.12)]" aria-hidden="true">01</span>
<div class="absolute inset-x-0 top-1/2 z-3 -translate-y-1/2 flex items-center justify-between px-4 py-3 bg-tih14-bg opacity-0 [clip-path:inset(100%_0_100%_0)] transition-[clip-path,opacity] duration-500 ease-tih14 group-hover:opacity-100 group-hover:[clip-path:inset(0)] focus-within:opacity-100 focus-within:[clip-path:inset(0)] motion-reduce:transition-none motion-reduce:opacity-100 motion-reduce:[clip-path:inset(0)]">
<p class="text-xs font-bold text-tih14-text">Digital Canvas</p>
<a href="#digital-canvas" class="px-2.5 py-1 rounded-full text-[10px] font-bold text-white bg-tih14-acc no-underline focus-visible:outline-2 focus-visible:outline-tih14-text focus-visible:outline-offset-2">View</a>
</div>
</article>
<article class="group relative aspect-[3/4] rounded-[14px] overflow-hidden">
<div class="absolute inset-0 grid place-items-center bg-[image:url('https://picsum.photos/seed/tih14-growth/600/800'),linear-gradient(135deg,oklch(0.25_0.05_180),oklch(0.42_0.09_165),oklch(0.7_0.15_163))] bg-cover bg-center bg-no-repeat [clip-path:polygon(0_0,100%_0,100%_50.5%,0_50.5%)] will-change-transform transition-[translate] duration-500 ease-tih14 group-hover:[translate:0_-6%] motion-reduce:transition-none motion-reduce:group-hover:[translate:0_0]">
</div>
<div class="absolute inset-0 grid place-items-center bg-[image:url('https://picsum.photos/seed/tih14-growth/600/800'),linear-gradient(135deg,oklch(0.25_0.05_180),oklch(0.42_0.09_165),oklch(0.7_0.15_163))] bg-cover bg-center bg-no-repeat [clip-path:polygon(0_49.5%,100%_49.5%,100%_100%,0_100%)] will-change-transform transition-[translate] duration-500 ease-tih14 group-hover:[translate:0_6%] motion-reduce:transition-none motion-reduce:group-hover:[translate:0_0]">
</div>
<span class="absolute top-3 left-3 z-2 text-[22px] font-black leading-none text-[oklch(1_0_0/0.12)]" aria-hidden="true">02</span>
<div class="absolute inset-x-0 top-1/2 z-3 -translate-y-1/2 flex items-center justify-between px-4 py-3 bg-tih14-bg opacity-0 [clip-path:inset(100%_0_100%_0)] transition-[clip-path,opacity] duration-500 ease-tih14 group-hover:opacity-100 group-hover:[clip-path:inset(0)] focus-within:opacity-100 focus-within:[clip-path:inset(0)] motion-reduce:transition-none motion-reduce:opacity-100 motion-reduce:[clip-path:inset(0)]">
<p class="text-xs font-bold text-tih14-text">Growth Series</p>
<a href="#growth-series" class="px-2.5 py-1 rounded-full text-[10px] font-bold text-white bg-tih14-acc no-underline focus-visible:outline-2 focus-visible:outline-tih14-text focus-visible:outline-offset-2">View</a>
</div>
</article>
<article class="group relative aspect-[3/4] rounded-[14px] overflow-hidden">
<div class="absolute inset-0 grid place-items-center bg-[image:url('https://picsum.photos/seed/tih14-power/600/800'),linear-gradient(135deg,oklch(0.18_0.03_60),oklch(0.45_0.11_60),oklch(0.78_0.16_72))] bg-cover bg-center bg-no-repeat [clip-path:polygon(0_0,100%_0,100%_50.5%,0_50.5%)] will-change-transform transition-[translate] duration-500 ease-tih14 group-hover:[translate:0_-6%] motion-reduce:transition-none motion-reduce:group-hover:[translate:0_0]">
</div>
<div class="absolute inset-0 grid place-items-center bg-[image:url('https://picsum.photos/seed/tih14-power/600/800'),linear-gradient(135deg,oklch(0.18_0.03_60),oklch(0.45_0.11_60),oklch(0.78_0.16_72))] bg-cover bg-center bg-no-repeat [clip-path:polygon(0_49.5%,100%_49.5%,100%_100%,0_100%)] will-change-transform transition-[translate] duration-500 ease-tih14 group-hover:[translate:0_6%] motion-reduce:transition-none motion-reduce:group-hover:[translate:0_0]">
</div>
<span class="absolute top-3 left-3 z-2 text-[22px] font-black leading-none text-[oklch(1_0_0/0.12)]" aria-hidden="true">03</span>
<div class="absolute inset-x-0 top-1/2 z-3 -translate-y-1/2 flex items-center justify-between px-4 py-3 bg-tih14-bg opacity-0 [clip-path:inset(100%_0_100%_0)] transition-[clip-path,opacity] duration-500 ease-tih14 group-hover:opacity-100 group-hover:[clip-path:inset(0)] focus-within:opacity-100 focus-within:[clip-path:inset(0)] motion-reduce:transition-none motion-reduce:opacity-100 motion-reduce:[clip-path:inset(0)]">
<p class="text-xs font-bold text-tih14-text">Power Study</p>
<a href="#power-study" class="px-2.5 py-1 rounded-full text-[10px] font-bold text-white bg-tih14-acc no-underline focus-visible:outline-2 focus-visible:outline-tih14-text focus-visible:outline-offset-2">View</a>
</div>
</article>
</div>
</section>@import "tailwindcss";
@theme {
--color-tih14-bg: #070710;
--color-tih14-bg: oklch(0.11 0.012 285);
--color-tih14-text: #f1f5f9;
--color-tih14-text: oklch(0.96 0.005 250);
--color-tih14-muted: #475569;
--color-tih14-muted: oklch(0.52 0.03 255);
--color-tih14-acc: #fb7185;
--color-tih14-acc: oklch(0.7 0.17 15);
--font-tih14-sans: 'Space Grotesk', system-ui, sans-serif;
--ease-tih14: cubic-bezier(0.34, 1.56, 0.64, 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-14 {
width: 100%;
min-height: 100svh;
}
.tih-14 ::selection {
background: oklch(0.7 0.17 15);
color: #000;
}@import "tailwindcss";
@theme {
--color-tih14-bg: #070710;
--color-tih14-bg: oklch(0.11 0.012 285);
--color-tih14-text: #f1f5f9;
--color-tih14-text: oklch(0.96 0.005 250);
--color-tih14-muted: #475569;
--color-tih14-muted: oklch(0.52 0.03 255);
--color-tih14-acc: #fb7185;
--color-tih14-acc: oklch(0.7 0.17 15);
--font-tih14-sans: 'Space Grotesk', system-ui, sans-serif;
--ease-tih14: cubic-bezier(0.34, 1.56, 0.64, 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-14 {
width: 100%;
min-height: 100svh;
}
.tih-14 ::selection {
background: oklch(0.7 0.17 15);
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-tih14-bg: #070710;
--color-tih14-bg: oklch(0.11 0.012 285);
--color-tih14-text: #f1f5f9;
--color-tih14-text: oklch(0.96 0.005 250);
--color-tih14-muted: #475569;
--color-tih14-muted: oklch(0.52 0.03 255);
--color-tih14-acc: #fb7185;
--color-tih14-acc: oklch(0.7 0.17 15);
--font-tih14-sans: 'Space Grotesk', system-ui, sans-serif;
--ease-tih14: cubic-bezier(0.34, 1.56, 0.64, 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-14 {
width: 100%;
min-height: 100svh;
}
.tih-14 ::selection {
background: oklch(0.7 0.17 15);
color: #000;
}@import "tailwindcss";
@theme {
--color-tih14-bg: #070710;
--color-tih14-bg: oklch(0.11 0.012 285);
--color-tih14-text: #f1f5f9;
--color-tih14-text: oklch(0.96 0.005 250);
--color-tih14-muted: #475569;
--color-tih14-muted: oklch(0.52 0.03 255);
--color-tih14-acc: #fb7185;
--color-tih14-acc: oklch(0.7 0.17 15);
--font-tih14-sans: 'Space Grotesk', system-ui, sans-serif;
--ease-tih14: cubic-bezier(0.34, 1.56, 0.64, 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-14 {
width: 100%;
min-height: 100svh;
}
.tih-14 ::selection {
background: oklch(0.7 0.17 15);
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.
- Each half now states its own clip and its own travel, so the complementary pair can be compared line by line — and the
50.5%/49.5%overlap that fixes the Chrome seam is visible rather than buried in a comment. - The reveal strip's two clip states sit adjacent on one element, which matters because the wipe only reads correctly if its timing matches the halves'.
- The duplicated background utility on both halves is the port's one real redundancy. It is also the illusion's hard requirement, so having it stated twice next to each clip is arguably safer than one shared rule.
transition-[translate]andtransition-[clip-path,opacity]name the individual properties v4's utilities actually set.focus-within:on the strip is added by the port so its CTA is reachable; in the CSS original the link is only visible on hover.motion-reduce:leaves the card split-free with the strip open — a static caption card, which is the right no-motion form.
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 Split Transition Hover
Source: https://codefronts.com/motion/tailwind-css-image-hover-effects/tailwind-image-split-transition-hover/
The card slices in half and an action strip wipes open in the gap. Two layers carry identical artwork and complementary clip-path polygons; the strip animates inset(100%_0_100%_0) to inset(0), so it opens from the centre line outward rather than fading in.
## HTML
```html
<section class="tih-14 w-full min-h-svh grid place-items-center bg-tih14-bg font-tih14-sans px-6 py-10" aria-label="Image split transition hover demo">
<div class="grid w-full max-w-195 gap-5 grid-cols-1 sm:grid-cols-3">
<article class="group relative aspect-[3/4] rounded-[14px] overflow-hidden">
<div class="absolute inset-0 grid place-items-center bg-[image:url('https://picsum.photos/seed/tih14-canvas/600/800'),linear-gradient(135deg,oklch(0.17_0.07_310),oklch(0.35_0.18_298),oklch(0.55_0.24_295))] bg-cover bg-center bg-no-repeat [clip-path:polygon(0_0,100%_0,100%_50.5%,0_50.5%)] will-change-transform transition-[translate] duration-500 ease-tih14 group-hover:[translate:0_-6%] motion-reduce:transition-none motion-reduce:group-hover:[translate:0_0]">
</div>
<div class="absolute inset-0 grid place-items-center bg-[image:url('https://picsum.photos/seed/tih14-canvas/600/800'),linear-gradient(135deg,oklch(0.17_0.07_310),oklch(0.35_0.18_298),oklch(0.55_0.24_295))] bg-cover bg-center bg-no-repeat [clip-path:polygon(0_49.5%,100%_49.5%,100%_100%,0_100%)] will-change-transform transition-[translate] duration-500 ease-tih14 group-hover:[translate:0_6%] motion-reduce:transition-none motion-reduce:group-hover:[translate:0_0]">
</div>
<span class="absolute top-3 left-3 z-2 text-[22px] font-black leading-none text-[oklch(1_0_0/0.12)]" aria-hidden="true">01</span>
<div class="absolute inset-x-0 top-1/2 z-3 -translate-y-1/2 flex items-center justify-between px-4 py-3 bg-tih14-bg opacity-0 [clip-path:inset(100%_0_100%_0)] transition-[clip-path,opacity] duration-500 ease-tih14 group-hover:opacity-100 group-hover:[clip-path:inset(0)] focus-within:opacity-100 focus-within:[clip-path:inset(0)] motion-reduce:transition-none motion-reduce:opacity-100 motion-reduce:[clip-path:inset(0)]">
<p class="text-xs font-bold text-tih14-text">Digital Canvas</p>
<a href="#digital-canvas" class="px-2.5 py-1 rounded-full text-[10px] font-bold text-white bg-tih14-acc no-underline focus-visible:outline-2 focus-visible:outline-tih14-text focus-visible:outline-offset-2">View</a>
</div>
</article>
<article class="group relative aspect-[3/4] rounded-[14px] overflow-hidden">
<div class="absolute inset-0 grid place-items-center bg-[image:url('https://picsum.photos/seed/tih14-growth/600/800'),linear-gradient(135deg,oklch(0.25_0.05_180),oklch(0.42_0.09_165),oklch(0.7_0.15_163))] bg-cover bg-center bg-no-repeat [clip-path:polygon(0_0,100%_0,100%_50.5%,0_50.5%)] will-change-transform transition-[translate] duration-500 ease-tih14 group-hover:[translate:0_-6%] motion-reduce:transition-none motion-reduce:group-hover:[translate:0_0]">
</div>
<div class="absolute inset-0 grid place-items-center bg-[image:url('https://picsum.photos/seed/tih14-growth/600/800'),linear-gradient(135deg,oklch(0.25_0.05_180),oklch(0.42_0.09_165),oklch(0.7_0.15_163))] bg-cover bg-center bg-no-repeat [clip-path:polygon(0_49.5%,100%_49.5%,100%_100%,0_100%)] will-change-transform transition-[translate] duration-500 ease-tih14 group-hover:[translate:0_6%] motion-reduce:transition-none motion-reduce:group-hover:[translate:0_0]">
</div>
<span class="absolute top-3 left-3 z-2 text-[22px] font-black leading-none text-[oklch(1_0_0/0.12)]" aria-hidden="true">02</span>
<div class="absolute inset-x-0 top-1/2 z-3 -translate-y-1/2 flex items-center justify-between px-4 py-3 bg-tih14-bg opacity-0 [clip-path:inset(100%_0_100%_0)] transition-[clip-path,opacity] duration-500 ease-tih14 group-hover:opacity-100 group-hover:[clip-path:inset(0)] focus-within:opacity-100 focus-within:[clip-path:inset(0)] motion-reduce:transition-none motion-reduce:opacity-100 motion-reduce:[clip-path:inset(0)]">
<p class="text-xs font-bold text-tih14-text">Growth Series</p>
<a href="#growth-series" class="px-2.5 py-1 rounded-full text-[10px] font-bold text-white bg-tih14-acc no-underline focus-visible:outline-2 focus-visible:outline-tih14-text focus-visible:outline-offset-2">View</a>
</div>
</article>
<article class="group relative aspect-[3/4] rounded-[14px] overflow-hidden">
<div class="absolute inset-0 grid place-items-center bg-[image:url('https://picsum.photos/seed/tih14-power/600/800'),linear-gradient(135deg,oklch(0.18_0.03_60),oklch(0.45_0.11_60),oklch(0.78_0.16_72))] bg-cover bg-center bg-no-repeat [clip-path:polygon(0_0,100%_0,100%_50.5%,0_50.5%)] will-change-transform transition-[translate] duration-500 ease-tih14 group-hover:[translate:0_-6%] motion-reduce:transition-none motion-reduce:group-hover:[translate:0_0]">
</div>
<div class="absolute inset-0 grid place-items-center bg-[image:url('https://picsum.photos/seed/tih14-power/600/800'),linear-gradient(135deg,oklch(0.18_0.03_60),oklch(0.45_0.11_60),oklch(0.78_0.16_72))] bg-cover bg-center bg-no-repeat [clip-path:polygon(0_49.5%,100%_49.5%,100%_100%,0_100%)] will-change-transform transition-[translate] duration-500 ease-tih14 group-hover:[translate:0_6%] motion-reduce:transition-none motion-reduce:group-hover:[translate:0_0]">
</div>
<span class="absolute top-3 left-3 z-2 text-[22px] font-black leading-none text-[oklch(1_0_0/0.12)]" aria-hidden="true">03</span>
<div class="absolute inset-x-0 top-1/2 z-3 -translate-y-1/2 flex items-center justify-between px-4 py-3 bg-tih14-bg opacity-0 [clip-path:inset(100%_0_100%_0)] transition-[clip-path,opacity] duration-500 ease-tih14 group-hover:opacity-100 group-hover:[clip-path:inset(0)] focus-within:opacity-100 focus-within:[clip-path:inset(0)] motion-reduce:transition-none motion-reduce:opacity-100 motion-reduce:[clip-path:inset(0)]">
<p class="text-xs font-bold text-tih14-text">Power Study</p>
<a href="#power-study" class="px-2.5 py-1 rounded-full text-[10px] font-bold text-white bg-tih14-acc no-underline focus-visible:outline-2 focus-visible:outline-tih14-text focus-visible:outline-offset-2">View</a>
</div>
</article>
</div>
</section>
```
## CSS
```css
@import "tailwindcss";
@theme {
--color-tih14-bg: #070710;
--color-tih14-bg: oklch(0.11 0.012 285);
--color-tih14-text: #f1f5f9;
--color-tih14-text: oklch(0.96 0.005 250);
--color-tih14-muted: #475569;
--color-tih14-muted: oklch(0.52 0.03 255);
--color-tih14-acc: #fb7185;
--color-tih14-acc: oklch(0.7 0.17 15);
--font-tih14-sans: 'Space Grotesk', system-ui, sans-serif;
--ease-tih14: cubic-bezier(0.34, 1.56, 0.64, 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-14 {
width: 100%;
min-height: 100svh;
}
.tih-14 ::selection {
background: oklch(0.7 0.17 15);
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 Split Transition Hover
Source: https://codefronts.com/motion/tailwind-css-image-hover-effects/tailwind-image-split-transition-hover/
The card slices in half and an action strip wipes open in the gap. Two layers carry identical artwork and complementary clip-path polygons; the strip animates inset(100%_0_100%_0) to inset(0), so it opens from the centre line outward rather than fading in.
## HTML
```html
<section class="tih-14 w-full min-h-svh grid place-items-center bg-tih14-bg font-tih14-sans px-6 py-10" aria-label="Image split transition hover demo">
<div class="grid w-full max-w-195 gap-5 grid-cols-1 sm:grid-cols-3">
<article class="group relative aspect-[3/4] rounded-[14px] overflow-hidden">
<div class="absolute inset-0 grid place-items-center bg-[image:url('https://picsum.photos/seed/tih14-canvas/600/800'),linear-gradient(135deg,oklch(0.17_0.07_310),oklch(0.35_0.18_298),oklch(0.55_0.24_295))] bg-cover bg-center bg-no-repeat [clip-path:polygon(0_0,100%_0,100%_50.5%,0_50.5%)] will-change-transform transition-[translate] duration-500 ease-tih14 group-hover:[translate:0_-6%] motion-reduce:transition-none motion-reduce:group-hover:[translate:0_0]">
</div>
<div class="absolute inset-0 grid place-items-center bg-[image:url('https://picsum.photos/seed/tih14-canvas/600/800'),linear-gradient(135deg,oklch(0.17_0.07_310),oklch(0.35_0.18_298),oklch(0.55_0.24_295))] bg-cover bg-center bg-no-repeat [clip-path:polygon(0_49.5%,100%_49.5%,100%_100%,0_100%)] will-change-transform transition-[translate] duration-500 ease-tih14 group-hover:[translate:0_6%] motion-reduce:transition-none motion-reduce:group-hover:[translate:0_0]">
</div>
<span class="absolute top-3 left-3 z-2 text-[22px] font-black leading-none text-[oklch(1_0_0/0.12)]" aria-hidden="true">01</span>
<div class="absolute inset-x-0 top-1/2 z-3 -translate-y-1/2 flex items-center justify-between px-4 py-3 bg-tih14-bg opacity-0 [clip-path:inset(100%_0_100%_0)] transition-[clip-path,opacity] duration-500 ease-tih14 group-hover:opacity-100 group-hover:[clip-path:inset(0)] focus-within:opacity-100 focus-within:[clip-path:inset(0)] motion-reduce:transition-none motion-reduce:opacity-100 motion-reduce:[clip-path:inset(0)]">
<p class="text-xs font-bold text-tih14-text">Digital Canvas</p>
<a href="#digital-canvas" class="px-2.5 py-1 rounded-full text-[10px] font-bold text-white bg-tih14-acc no-underline focus-visible:outline-2 focus-visible:outline-tih14-text focus-visible:outline-offset-2">View</a>
</div>
</article>
<article class="group relative aspect-[3/4] rounded-[14px] overflow-hidden">
<div class="absolute inset-0 grid place-items-center bg-[image:url('https://picsum.photos/seed/tih14-growth/600/800'),linear-gradient(135deg,oklch(0.25_0.05_180),oklch(0.42_0.09_165),oklch(0.7_0.15_163))] bg-cover bg-center bg-no-repeat [clip-path:polygon(0_0,100%_0,100%_50.5%,0_50.5%)] will-change-transform transition-[translate] duration-500 ease-tih14 group-hover:[translate:0_-6%] motion-reduce:transition-none motion-reduce:group-hover:[translate:0_0]">
</div>
<div class="absolute inset-0 grid place-items-center bg-[image:url('https://picsum.photos/seed/tih14-growth/600/800'),linear-gradient(135deg,oklch(0.25_0.05_180),oklch(0.42_0.09_165),oklch(0.7_0.15_163))] bg-cover bg-center bg-no-repeat [clip-path:polygon(0_49.5%,100%_49.5%,100%_100%,0_100%)] will-change-transform transition-[translate] duration-500 ease-tih14 group-hover:[translate:0_6%] motion-reduce:transition-none motion-reduce:group-hover:[translate:0_0]">
</div>
<span class="absolute top-3 left-3 z-2 text-[22px] font-black leading-none text-[oklch(1_0_0/0.12)]" aria-hidden="true">02</span>
<div class="absolute inset-x-0 top-1/2 z-3 -translate-y-1/2 flex items-center justify-between px-4 py-3 bg-tih14-bg opacity-0 [clip-path:inset(100%_0_100%_0)] transition-[clip-path,opacity] duration-500 ease-tih14 group-hover:opacity-100 group-hover:[clip-path:inset(0)] focus-within:opacity-100 focus-within:[clip-path:inset(0)] motion-reduce:transition-none motion-reduce:opacity-100 motion-reduce:[clip-path:inset(0)]">
<p class="text-xs font-bold text-tih14-text">Growth Series</p>
<a href="#growth-series" class="px-2.5 py-1 rounded-full text-[10px] font-bold text-white bg-tih14-acc no-underline focus-visible:outline-2 focus-visible:outline-tih14-text focus-visible:outline-offset-2">View</a>
</div>
</article>
<article class="group relative aspect-[3/4] rounded-[14px] overflow-hidden">
<div class="absolute inset-0 grid place-items-center bg-[image:url('https://picsum.photos/seed/tih14-power/600/800'),linear-gradient(135deg,oklch(0.18_0.03_60),oklch(0.45_0.11_60),oklch(0.78_0.16_72))] bg-cover bg-center bg-no-repeat [clip-path:polygon(0_0,100%_0,100%_50.5%,0_50.5%)] will-change-transform transition-[translate] duration-500 ease-tih14 group-hover:[translate:0_-6%] motion-reduce:transition-none motion-reduce:group-hover:[translate:0_0]">
</div>
<div class="absolute inset-0 grid place-items-center bg-[image:url('https://picsum.photos/seed/tih14-power/600/800'),linear-gradient(135deg,oklch(0.18_0.03_60),oklch(0.45_0.11_60),oklch(0.78_0.16_72))] bg-cover bg-center bg-no-repeat [clip-path:polygon(0_49.5%,100%_49.5%,100%_100%,0_100%)] will-change-transform transition-[translate] duration-500 ease-tih14 group-hover:[translate:0_6%] motion-reduce:transition-none motion-reduce:group-hover:[translate:0_0]">
</div>
<span class="absolute top-3 left-3 z-2 text-[22px] font-black leading-none text-[oklch(1_0_0/0.12)]" aria-hidden="true">03</span>
<div class="absolute inset-x-0 top-1/2 z-3 -translate-y-1/2 flex items-center justify-between px-4 py-3 bg-tih14-bg opacity-0 [clip-path:inset(100%_0_100%_0)] transition-[clip-path,opacity] duration-500 ease-tih14 group-hover:opacity-100 group-hover:[clip-path:inset(0)] focus-within:opacity-100 focus-within:[clip-path:inset(0)] motion-reduce:transition-none motion-reduce:opacity-100 motion-reduce:[clip-path:inset(0)]">
<p class="text-xs font-bold text-tih14-text">Power Study</p>
<a href="#power-study" class="px-2.5 py-1 rounded-full text-[10px] font-bold text-white bg-tih14-acc no-underline focus-visible:outline-2 focus-visible:outline-tih14-text focus-visible:outline-offset-2">View</a>
</div>
</article>
</div>
</section>
```
## CSS
```css
@import "tailwindcss";
@theme {
--color-tih14-bg: #070710;
--color-tih14-bg: oklch(0.11 0.012 285);
--color-tih14-text: #f1f5f9;
--color-tih14-text: oklch(0.96 0.005 250);
--color-tih14-muted: #475569;
--color-tih14-muted: oklch(0.52 0.03 255);
--color-tih14-acc: #fb7185;
--color-tih14-acc: oklch(0.7 0.17 15);
--font-tih14-sans: 'Space Grotesk', system-ui, sans-serif;
--ease-tih14: cubic-bezier(0.34, 1.56, 0.64, 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-14 {
width: 100%;
min-height: 100svh;
}
.tih-14 ::selection {
background: oklch(0.7 0.17 15);
color: #000;
}
```How this works
Two halves, one image, two class lists. Each half is the full artwork clipped to one side; on hover they translate apart by 6%. Because both halves carry the same background utility, the seam is invisible — and because the polygons meet at 50.5% rather than 50%, sub-pixel rounding cannot open a hairline gap at rest.
The strip wipes, not fades.
class="[clip-path:inset(100%_0_100%_0)] opacity-0
transition-[clip-path,opacity] duration-500 ease-tih14
group-hover:[clip-path:inset(0)] group-hover:opacity-100"inset() clipped 100% from both top and bottom is a zero-height line at the centre; animating to inset(0) grows it symmetrically into the gap the halves just opened. One shared duration keeps the two motions in step.
Make it yours
- Split ratio: change both polygons' shared edge (e.g.
40.5%) for an asymmetric slice. - Drama: the
6%in the two translate utilities.12%is theatrical,3%is a breath. - Vertical split: left/right polygons with
[translate:-6%_0]/[translate:6%_0]. - True before/after: give the two halves different background utilities — they are independent elements.
- Page-peel: add
group-hover:rotate-x-3to the top half withtransform-3don the card.
Gotchas — read before shipping
- Both halves must carry the same background. If the two utilities drift apart, the seam becomes visible at rest — which is the one thing this illusion cannot survive.
- Use
50.5%, not50%, on the shared edge. Chrome's sub-pixel rounding shows a 1px line otherwise. - The strip's timing must match the halves'. Open it faster and it appears before there is a gap to appear in.
inset()arbitrary values need underscores:inset(100%_0_100%_0).- The card's
overflow-hiddenis required — the halves travel outside the frame. - 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+ |
clip-path polygon and inset() transitions work in all modern engines; Safari needs 13.1+ for reliable inset() interpolation.