22 / 22
All 22 in 22 Tailwind CSS Image Carousel
- 01Tailwind E-commerce Product Gallery Carousel with Thumbnails
- 02Tailwind Shop the Look Multi-Item Card Slider with Scroll Snap
- 03Tailwind Infinite Logo Scroller Marquee with No JavaScript
- 04Tailwind Product Colour Variant Picker Slider
- 05Tailwind Full-Screen Hero Slideshow with Auto Cross-Fade
- 06Tailwind Testimonial Card Carousel with Star Ratings
- 07Tailwind Meet the Team Profile Slider with Circular Portraits
- 08Tailwind Portfolio Gallery Slider with Hover Caption Reveal
- 09Tailwind Netflix-Style Content Row Carousel with Hover Expand
- 10Tailwind Magazine Split-Screen Article Slider
- 11Tailwind Onboarding Slider with Native CSS Scroll-Marker Dots
- 12Tailwind Vertical Image Carousel with Y-Axis Scroll Snap
- 13Tailwind 3D Coverflow Carousel with Perspective Transforms
- 14Tailwind Cross-Fade Image Slideshow with Manual Controls
- 15Tailwind Dual Opposite-Direction Marquee Slider
- 16Tailwind Dot Pagination Carousel with Target and Has Selectors
- 17Tailwind Prev / Next Arrow Carousel with Native Scroll Buttons
- 18Tailwind Before / After Image Comparison Slider
- 19Tailwind Accordion Expanding Image Panel Carousel
- 20Tailwind Autoplay Slider with Keyframe Track and Progress Bars
- 21Tailwind Zoom-on-Hover Image Gallery Slider
- 22Tailwind Parallax Text-Over-Image Story Slider
Tailwind Parallax Text-Over-Image Story Slider
A presentation carousel where, on each transition, the photograph and the headline travel different distances at different speeds. The depth illusion is entirely a mismatch in two numbers, and Tailwind puts both numbers on the elements they move.
Untitled UI Pro: 5,000+ React + Tailwind CSS v4 components · from $349 one-time
Untitled UI React · Affiliate link
The code
<section class="tcar-22 w-full min-h-svh grid place-items-center bg-tcar22-bg font-tcar22-sans px-5 py-10" aria-label="Parallax story slider">
<div class="group relative w-[min(760px,100%)]">
<input type="radio" name="tcar-22" id="tcar-22-1" class="sr-only" checked>
<input type="radio" name="tcar-22" id="tcar-22-2" class="sr-only">
<input type="radio" name="tcar-22" id="tcar-22-3" class="sr-only">
<div class="relative aspect-[12/7] rounded-[18px] overflow-hidden shadow-[0_30px_60px_-34px_oklch(0_0_0/0.9)]">
<article class="absolute inset-0 opacity-0 pointer-events-none transition-opacity duration-700 group-has-[#tcar-22-1:checked]:opacity-100 group-has-[#tcar-22-1:checked]:pointer-events-auto">
<img src="https://picsum.photos/seed/plx-1/1200/700" width="1200" height="700" fetchpriority="high" decoding="async" alt="Canyon at sunrise" class="absolute inset-0 size-full object-cover scale-[1.12] translate-x-[6%] transition-[scale,translate] duration-1000 ease-[cubic-bezier(0.2,0.8,0.2,1)] group-has-[#tcar-22-1:checked]:scale-[1.06] group-has-[#tcar-22-1:checked]:translate-x-0 motion-reduce:transition-none motion-reduce:scale-100 motion-reduce:translate-x-0">
<div aria-hidden="true" class="absolute inset-0 bg-[linear-gradient(90deg,oklch(0.14_0.01_265/0.82),transparent_65%)]"></div>
<div class="absolute left-0 bottom-0 z-[2] p-[clamp(22px,5vw,52px)] max-w-[70%] text-white -translate-x-[14%] opacity-0 transition-[translate,opacity] duration-[800ms] delay-[120ms] ease-[cubic-bezier(0.2,0.8,0.2,1)] group-has-[#tcar-22-1:checked]:translate-x-0 group-has-[#tcar-22-1:checked]:opacity-100 motion-reduce:transition-opacity motion-reduce:translate-x-0">
<p class="text-xs tracking-[0.2em] uppercase text-tcar22-acc mb-2.5">Chapter 01</p>
<h3 class="text-[clamp(26px,5vw,44px)] font-extrabold leading-[1.05] tracking-[-0.01em] m-0 [text-shadow:0_2px_20px_oklch(0_0_0/0.5)]">Into the canyon</h3>
<p class="text-[15px] leading-[1.55] text-tcar22-lead mt-3 max-w-[36ch]">Where light carves the rock a little differently every hour.</p>
</div>
</article>
<article class="absolute inset-0 opacity-0 pointer-events-none transition-opacity duration-700 group-has-[#tcar-22-2:checked]:opacity-100 group-has-[#tcar-22-2:checked]:pointer-events-auto">
<img src="https://picsum.photos/seed/plx-2/1200/700" width="1200" height="700" loading="lazy" decoding="async" alt="Open ocean" class="absolute inset-0 size-full object-cover scale-[1.12] translate-x-[6%] transition-[scale,translate] duration-1000 ease-[cubic-bezier(0.2,0.8,0.2,1)] group-has-[#tcar-22-2:checked]:scale-[1.06] group-has-[#tcar-22-2:checked]:translate-x-0 motion-reduce:transition-none motion-reduce:scale-100 motion-reduce:translate-x-0">
<div aria-hidden="true" class="absolute inset-0 bg-[linear-gradient(90deg,oklch(0.14_0.01_265/0.82),transparent_65%)]"></div>
<div class="absolute left-0 bottom-0 z-[2] p-[clamp(22px,5vw,52px)] max-w-[70%] text-white -translate-x-[14%] opacity-0 transition-[translate,opacity] duration-[800ms] delay-[120ms] ease-[cubic-bezier(0.2,0.8,0.2,1)] group-has-[#tcar-22-2:checked]:translate-x-0 group-has-[#tcar-22-2:checked]:opacity-100 motion-reduce:transition-opacity motion-reduce:translate-x-0">
<p class="text-xs tracking-[0.2em] uppercase text-tcar22-acc mb-2.5">Chapter 02</p>
<h3 class="text-[clamp(26px,5vw,44px)] font-extrabold leading-[1.05] tracking-[-0.01em] m-0 [text-shadow:0_2px_20px_oklch(0_0_0/0.5)]">Beyond the shore</h3>
<p class="text-[15px] leading-[1.55] text-tcar22-lead mt-3 max-w-[36ch]">Nothing but horizon, and the sound of the hull.</p>
</div>
</article>
<article class="absolute inset-0 opacity-0 pointer-events-none transition-opacity duration-700 group-has-[#tcar-22-3:checked]:opacity-100 group-has-[#tcar-22-3:checked]:pointer-events-auto">
<img src="https://picsum.photos/seed/plx-3/1200/700" width="1200" height="700" loading="lazy" decoding="async" alt="Alpine ridge" class="absolute inset-0 size-full object-cover scale-[1.12] translate-x-[6%] transition-[scale,translate] duration-1000 ease-[cubic-bezier(0.2,0.8,0.2,1)] group-has-[#tcar-22-3:checked]:scale-[1.06] group-has-[#tcar-22-3:checked]:translate-x-0 motion-reduce:transition-none motion-reduce:scale-100 motion-reduce:translate-x-0">
<div aria-hidden="true" class="absolute inset-0 bg-[linear-gradient(90deg,oklch(0.14_0.01_265/0.82),transparent_65%)]"></div>
<div class="absolute left-0 bottom-0 z-[2] p-[clamp(22px,5vw,52px)] max-w-[70%] text-white -translate-x-[14%] opacity-0 transition-[translate,opacity] duration-[800ms] delay-[120ms] ease-[cubic-bezier(0.2,0.8,0.2,1)] group-has-[#tcar-22-3:checked]:translate-x-0 group-has-[#tcar-22-3:checked]:opacity-100 motion-reduce:transition-opacity motion-reduce:translate-x-0">
<p class="text-xs tracking-[0.2em] uppercase text-tcar22-acc mb-2.5">Chapter 03</p>
<h3 class="text-[clamp(26px,5vw,44px)] font-extrabold leading-[1.05] tracking-[-0.01em] m-0 [text-shadow:0_2px_20px_oklch(0_0_0/0.5)]">Above the clouds</h3>
<p class="text-[15px] leading-[1.55] text-tcar22-lead mt-3 max-w-[36ch]">The last ridge before the summit, and the quiet up there.</p>
</div>
</article>
</div>
<div class="absolute right-[clamp(2px,1.5vw,24px)] bottom-[clamp(2px,1.5vw,24px)] z-[3] flex">
<label for="tcar-22-1" aria-label="Chapter 1" class="group/pip size-11 grid place-items-center cursor-pointer"><span class="size-3 rounded-full bg-tcar22-pip shadow-[0_0_0_1px_oklch(0_0_0/0.35)] transition-[scale,background-color] duration-200 group-hover/pip:bg-tcar22-piphover group-has-[#tcar-22-1:checked]:bg-tcar22-acc group-has-[#tcar-22-1:checked]:scale-[1.3] group-has-[#tcar-22-1:focus-visible]:outline-3 group-has-[#tcar-22-1:focus-visible]:outline-tcar22-acc group-has-[#tcar-22-1:focus-visible]:outline-offset-[3px] motion-reduce:transition-none"></span></label>
<label for="tcar-22-2" aria-label="Chapter 2" class="group/pip size-11 grid place-items-center cursor-pointer"><span class="size-3 rounded-full bg-tcar22-pip shadow-[0_0_0_1px_oklch(0_0_0/0.35)] transition-[scale,background-color] duration-200 group-hover/pip:bg-tcar22-piphover group-has-[#tcar-22-2:checked]:bg-tcar22-acc group-has-[#tcar-22-2:checked]:scale-[1.3] group-has-[#tcar-22-2:focus-visible]:outline-3 group-has-[#tcar-22-2:focus-visible]:outline-tcar22-acc group-has-[#tcar-22-2:focus-visible]:outline-offset-[3px] motion-reduce:transition-none"></span></label>
<label for="tcar-22-3" aria-label="Chapter 3" class="group/pip size-11 grid place-items-center cursor-pointer"><span class="size-3 rounded-full bg-tcar22-pip shadow-[0_0_0_1px_oklch(0_0_0/0.35)] transition-[scale,background-color] duration-200 group-hover/pip:bg-tcar22-piphover group-has-[#tcar-22-3:checked]:bg-tcar22-acc group-has-[#tcar-22-3:checked]:scale-[1.3] group-has-[#tcar-22-3:focus-visible]:outline-3 group-has-[#tcar-22-3:focus-visible]:outline-tcar22-acc group-has-[#tcar-22-3:focus-visible]:outline-offset-[3px] motion-reduce:transition-none"></span></label>
</div>
</div>
</section><section class="tcar-22 w-full min-h-svh grid place-items-center bg-tcar22-bg font-tcar22-sans px-5 py-10" aria-label="Parallax story slider">
<div class="group relative w-[min(760px,100%)]">
<input type="radio" name="tcar-22" id="tcar-22-1" class="sr-only" checked>
<input type="radio" name="tcar-22" id="tcar-22-2" class="sr-only">
<input type="radio" name="tcar-22" id="tcar-22-3" class="sr-only">
<div class="relative aspect-[12/7] rounded-[18px] overflow-hidden shadow-[0_30px_60px_-34px_oklch(0_0_0/0.9)]">
<article class="absolute inset-0 opacity-0 pointer-events-none transition-opacity duration-700 group-has-[#tcar-22-1:checked]:opacity-100 group-has-[#tcar-22-1:checked]:pointer-events-auto">
<img src="https://picsum.photos/seed/plx-1/1200/700" width="1200" height="700" fetchpriority="high" decoding="async" alt="Canyon at sunrise" class="absolute inset-0 size-full object-cover scale-[1.12] translate-x-[6%] transition-[scale,translate] duration-1000 ease-[cubic-bezier(0.2,0.8,0.2,1)] group-has-[#tcar-22-1:checked]:scale-[1.06] group-has-[#tcar-22-1:checked]:translate-x-0 motion-reduce:transition-none motion-reduce:scale-100 motion-reduce:translate-x-0">
<div aria-hidden="true" class="absolute inset-0 bg-[linear-gradient(90deg,oklch(0.14_0.01_265/0.82),transparent_65%)]"></div>
<div class="absolute left-0 bottom-0 z-[2] p-[clamp(22px,5vw,52px)] max-w-[70%] text-white -translate-x-[14%] opacity-0 transition-[translate,opacity] duration-[800ms] delay-[120ms] ease-[cubic-bezier(0.2,0.8,0.2,1)] group-has-[#tcar-22-1:checked]:translate-x-0 group-has-[#tcar-22-1:checked]:opacity-100 motion-reduce:transition-opacity motion-reduce:translate-x-0">
<p class="text-xs tracking-[0.2em] uppercase text-tcar22-acc mb-2.5">Chapter 01</p>
<h3 class="text-[clamp(26px,5vw,44px)] font-extrabold leading-[1.05] tracking-[-0.01em] m-0 [text-shadow:0_2px_20px_oklch(0_0_0/0.5)]">Into the canyon</h3>
<p class="text-[15px] leading-[1.55] text-tcar22-lead mt-3 max-w-[36ch]">Where light carves the rock a little differently every hour.</p>
</div>
</article>
<article class="absolute inset-0 opacity-0 pointer-events-none transition-opacity duration-700 group-has-[#tcar-22-2:checked]:opacity-100 group-has-[#tcar-22-2:checked]:pointer-events-auto">
<img src="https://picsum.photos/seed/plx-2/1200/700" width="1200" height="700" loading="lazy" decoding="async" alt="Open ocean" class="absolute inset-0 size-full object-cover scale-[1.12] translate-x-[6%] transition-[scale,translate] duration-1000 ease-[cubic-bezier(0.2,0.8,0.2,1)] group-has-[#tcar-22-2:checked]:scale-[1.06] group-has-[#tcar-22-2:checked]:translate-x-0 motion-reduce:transition-none motion-reduce:scale-100 motion-reduce:translate-x-0">
<div aria-hidden="true" class="absolute inset-0 bg-[linear-gradient(90deg,oklch(0.14_0.01_265/0.82),transparent_65%)]"></div>
<div class="absolute left-0 bottom-0 z-[2] p-[clamp(22px,5vw,52px)] max-w-[70%] text-white -translate-x-[14%] opacity-0 transition-[translate,opacity] duration-[800ms] delay-[120ms] ease-[cubic-bezier(0.2,0.8,0.2,1)] group-has-[#tcar-22-2:checked]:translate-x-0 group-has-[#tcar-22-2:checked]:opacity-100 motion-reduce:transition-opacity motion-reduce:translate-x-0">
<p class="text-xs tracking-[0.2em] uppercase text-tcar22-acc mb-2.5">Chapter 02</p>
<h3 class="text-[clamp(26px,5vw,44px)] font-extrabold leading-[1.05] tracking-[-0.01em] m-0 [text-shadow:0_2px_20px_oklch(0_0_0/0.5)]">Beyond the shore</h3>
<p class="text-[15px] leading-[1.55] text-tcar22-lead mt-3 max-w-[36ch]">Nothing but horizon, and the sound of the hull.</p>
</div>
</article>
<article class="absolute inset-0 opacity-0 pointer-events-none transition-opacity duration-700 group-has-[#tcar-22-3:checked]:opacity-100 group-has-[#tcar-22-3:checked]:pointer-events-auto">
<img src="https://picsum.photos/seed/plx-3/1200/700" width="1200" height="700" loading="lazy" decoding="async" alt="Alpine ridge" class="absolute inset-0 size-full object-cover scale-[1.12] translate-x-[6%] transition-[scale,translate] duration-1000 ease-[cubic-bezier(0.2,0.8,0.2,1)] group-has-[#tcar-22-3:checked]:scale-[1.06] group-has-[#tcar-22-3:checked]:translate-x-0 motion-reduce:transition-none motion-reduce:scale-100 motion-reduce:translate-x-0">
<div aria-hidden="true" class="absolute inset-0 bg-[linear-gradient(90deg,oklch(0.14_0.01_265/0.82),transparent_65%)]"></div>
<div class="absolute left-0 bottom-0 z-[2] p-[clamp(22px,5vw,52px)] max-w-[70%] text-white -translate-x-[14%] opacity-0 transition-[translate,opacity] duration-[800ms] delay-[120ms] ease-[cubic-bezier(0.2,0.8,0.2,1)] group-has-[#tcar-22-3:checked]:translate-x-0 group-has-[#tcar-22-3:checked]:opacity-100 motion-reduce:transition-opacity motion-reduce:translate-x-0">
<p class="text-xs tracking-[0.2em] uppercase text-tcar22-acc mb-2.5">Chapter 03</p>
<h3 class="text-[clamp(26px,5vw,44px)] font-extrabold leading-[1.05] tracking-[-0.01em] m-0 [text-shadow:0_2px_20px_oklch(0_0_0/0.5)]">Above the clouds</h3>
<p class="text-[15px] leading-[1.55] text-tcar22-lead mt-3 max-w-[36ch]">The last ridge before the summit, and the quiet up there.</p>
</div>
</article>
</div>
<div class="absolute right-[clamp(2px,1.5vw,24px)] bottom-[clamp(2px,1.5vw,24px)] z-[3] flex">
<label for="tcar-22-1" aria-label="Chapter 1" class="group/pip size-11 grid place-items-center cursor-pointer"><span class="size-3 rounded-full bg-tcar22-pip shadow-[0_0_0_1px_oklch(0_0_0/0.35)] transition-[scale,background-color] duration-200 group-hover/pip:bg-tcar22-piphover group-has-[#tcar-22-1:checked]:bg-tcar22-acc group-has-[#tcar-22-1:checked]:scale-[1.3] group-has-[#tcar-22-1:focus-visible]:outline-3 group-has-[#tcar-22-1:focus-visible]:outline-tcar22-acc group-has-[#tcar-22-1:focus-visible]:outline-offset-[3px] motion-reduce:transition-none"></span></label>
<label for="tcar-22-2" aria-label="Chapter 2" class="group/pip size-11 grid place-items-center cursor-pointer"><span class="size-3 rounded-full bg-tcar22-pip shadow-[0_0_0_1px_oklch(0_0_0/0.35)] transition-[scale,background-color] duration-200 group-hover/pip:bg-tcar22-piphover group-has-[#tcar-22-2:checked]:bg-tcar22-acc group-has-[#tcar-22-2:checked]:scale-[1.3] group-has-[#tcar-22-2:focus-visible]:outline-3 group-has-[#tcar-22-2:focus-visible]:outline-tcar22-acc group-has-[#tcar-22-2:focus-visible]:outline-offset-[3px] motion-reduce:transition-none"></span></label>
<label for="tcar-22-3" aria-label="Chapter 3" class="group/pip size-11 grid place-items-center cursor-pointer"><span class="size-3 rounded-full bg-tcar22-pip shadow-[0_0_0_1px_oklch(0_0_0/0.35)] transition-[scale,background-color] duration-200 group-hover/pip:bg-tcar22-piphover group-has-[#tcar-22-3:checked]:bg-tcar22-acc group-has-[#tcar-22-3:checked]:scale-[1.3] group-has-[#tcar-22-3:focus-visible]:outline-3 group-has-[#tcar-22-3:focus-visible]:outline-tcar22-acc group-has-[#tcar-22-3:focus-visible]:outline-offset-[3px] motion-reduce:transition-none"></span></label>
</div>
</div>
</section>@import "tailwindcss";
@theme {
--color-tcar22-bg: #0c0d10;
--color-tcar22-bg: oklch(0.16 0.006 265);
--color-tcar22-lead: #dfe2e8;
--color-tcar22-lead: oklch(0.9 0.006 265);
--color-tcar22-pip: #ffffff;
--color-tcar22-pip: oklch(1 0 0 / 0.4);
--color-tcar22-piphover: #ffffff;
--color-tcar22-piphover: oklch(1 0 0 / 0.68);
--color-tcar22-acc: #f5c542;
--color-tcar22-acc: oklch(0.84 0.14 88);
--font-tcar22-sans: 'Archivo', system-ui, sans-serif;
}
.tcar-22 {
width: 100%;
min-height: 100svh;
}
.tcar-22 ::selection {
background: #fff;
color: #111;
}@import "tailwindcss";
@theme {
--color-tcar22-bg: #0c0d10;
--color-tcar22-bg: oklch(0.16 0.006 265);
--color-tcar22-lead: #dfe2e8;
--color-tcar22-lead: oklch(0.9 0.006 265);
--color-tcar22-pip: #ffffff;
--color-tcar22-pip: oklch(1 0 0 / 0.4);
--color-tcar22-piphover: #ffffff;
--color-tcar22-piphover: oklch(1 0 0 / 0.68);
--color-tcar22-acc: #f5c542;
--color-tcar22-acc: oklch(0.84 0.14 88);
--font-tcar22-sans: 'Archivo', system-ui, sans-serif;
}
.tcar-22 {
width: 100%;
min-height: 100svh;
}
.tcar-22 ::selection {
background: #fff;
color: #111;
}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-tcar22-bg: #0c0d10;
--color-tcar22-bg: oklch(0.16 0.006 265);
--color-tcar22-lead: #dfe2e8;
--color-tcar22-lead: oklch(0.9 0.006 265);
--color-tcar22-pip: #ffffff;
--color-tcar22-pip: oklch(1 0 0 / 0.4);
--color-tcar22-piphover: #ffffff;
--color-tcar22-piphover: oklch(1 0 0 / 0.68);
--color-tcar22-acc: #f5c542;
--color-tcar22-acc: oklch(0.84 0.14 88);
--font-tcar22-sans: 'Archivo', system-ui, sans-serif;
}
.tcar-22 {
width: 100%;
min-height: 100svh;
}
.tcar-22 ::selection {
background: #fff;
color: #111;
}@import "tailwindcss";
@theme {
--color-tcar22-bg: #0c0d10;
--color-tcar22-bg: oklch(0.16 0.006 265);
--color-tcar22-lead: #dfe2e8;
--color-tcar22-lead: oklch(0.9 0.006 265);
--color-tcar22-pip: #ffffff;
--color-tcar22-pip: oklch(1 0 0 / 0.4);
--color-tcar22-piphover: #ffffff;
--color-tcar22-piphover: oklch(1 0 0 / 0.68);
--color-tcar22-acc: #f5c542;
--color-tcar22-acc: oklch(0.84 0.14 88);
--font-tcar22-sans: 'Archivo', system-ui, sans-serif;
}
.tcar-22 {
width: 100%;
min-height: 100svh;
}
.tcar-22 ::selection {
background: #fff;
color: #111;
}<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=Archivo:wght@400;600;700;800;900&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=Archivo:wght@400;600;700;800;900&display=swap">What changed in the port
Which parts became utilities, which stayed CSS, and why.
- The parallax lives in four numbers — 6%, 14%, 1000ms, 800ms+120ms — and in Tailwind all four sit on the two elements they describe. The CSS version spread them across six selectors, which is why tuning it always meant scrolling.
transition-[scale,translate]names both individual transform properties. Under the oldtransformshorthand the image's scale and translate were one value and could not be tuned independently.- UI change from the CSS original: each pip label is now a 44px box with the 12px dot centred inside it (the original's pips were 12px of tappable area); the pips also gained a 1px dark ring, without which a white-at-40% idle pip disappears completely over a bright sky — the navigation was invisible on chapter 3. The lead paragraph lightened from
#dfe2e8to a token atoklch(0.9)so it holds 4.5:1 over the pale right-hand side of the third photograph, where the scrim has faded out.
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 Parallax Text-Over-Image Story Slider
Source: https://codefronts.com/snippets/tailwind-css-image-carousel/tailwind-parallax-text-over-image-story-slider/
A presentation carousel where, on each transition, the photograph and the headline travel different distances at different speeds. The depth illusion is entirely a mismatch in two numbers, and Tailwind puts both numbers on the elements they move.
## HTML
```html
<section class="tcar-22 w-full min-h-svh grid place-items-center bg-tcar22-bg font-tcar22-sans px-5 py-10" aria-label="Parallax story slider">
<div class="group relative w-[min(760px,100%)]">
<input type="radio" name="tcar-22" id="tcar-22-1" class="sr-only" checked>
<input type="radio" name="tcar-22" id="tcar-22-2" class="sr-only">
<input type="radio" name="tcar-22" id="tcar-22-3" class="sr-only">
<div class="relative aspect-[12/7] rounded-[18px] overflow-hidden shadow-[0_30px_60px_-34px_oklch(0_0_0/0.9)]">
<article class="absolute inset-0 opacity-0 pointer-events-none transition-opacity duration-700 group-has-[#tcar-22-1:checked]:opacity-100 group-has-[#tcar-22-1:checked]:pointer-events-auto">
<img src="https://picsum.photos/seed/plx-1/1200/700" width="1200" height="700" fetchpriority="high" decoding="async" alt="Canyon at sunrise" class="absolute inset-0 size-full object-cover scale-[1.12] translate-x-[6%] transition-[scale,translate] duration-1000 ease-[cubic-bezier(0.2,0.8,0.2,1)] group-has-[#tcar-22-1:checked]:scale-[1.06] group-has-[#tcar-22-1:checked]:translate-x-0 motion-reduce:transition-none motion-reduce:scale-100 motion-reduce:translate-x-0">
<div aria-hidden="true" class="absolute inset-0 bg-[linear-gradient(90deg,oklch(0.14_0.01_265/0.82),transparent_65%)]"></div>
<div class="absolute left-0 bottom-0 z-[2] p-[clamp(22px,5vw,52px)] max-w-[70%] text-white -translate-x-[14%] opacity-0 transition-[translate,opacity] duration-[800ms] delay-[120ms] ease-[cubic-bezier(0.2,0.8,0.2,1)] group-has-[#tcar-22-1:checked]:translate-x-0 group-has-[#tcar-22-1:checked]:opacity-100 motion-reduce:transition-opacity motion-reduce:translate-x-0">
<p class="text-xs tracking-[0.2em] uppercase text-tcar22-acc mb-2.5">Chapter 01</p>
<h3 class="text-[clamp(26px,5vw,44px)] font-extrabold leading-[1.05] tracking-[-0.01em] m-0 [text-shadow:0_2px_20px_oklch(0_0_0/0.5)]">Into the canyon</h3>
<p class="text-[15px] leading-[1.55] text-tcar22-lead mt-3 max-w-[36ch]">Where light carves the rock a little differently every hour.</p>
</div>
</article>
<article class="absolute inset-0 opacity-0 pointer-events-none transition-opacity duration-700 group-has-[#tcar-22-2:checked]:opacity-100 group-has-[#tcar-22-2:checked]:pointer-events-auto">
<img src="https://picsum.photos/seed/plx-2/1200/700" width="1200" height="700" loading="lazy" decoding="async" alt="Open ocean" class="absolute inset-0 size-full object-cover scale-[1.12] translate-x-[6%] transition-[scale,translate] duration-1000 ease-[cubic-bezier(0.2,0.8,0.2,1)] group-has-[#tcar-22-2:checked]:scale-[1.06] group-has-[#tcar-22-2:checked]:translate-x-0 motion-reduce:transition-none motion-reduce:scale-100 motion-reduce:translate-x-0">
<div aria-hidden="true" class="absolute inset-0 bg-[linear-gradient(90deg,oklch(0.14_0.01_265/0.82),transparent_65%)]"></div>
<div class="absolute left-0 bottom-0 z-[2] p-[clamp(22px,5vw,52px)] max-w-[70%] text-white -translate-x-[14%] opacity-0 transition-[translate,opacity] duration-[800ms] delay-[120ms] ease-[cubic-bezier(0.2,0.8,0.2,1)] group-has-[#tcar-22-2:checked]:translate-x-0 group-has-[#tcar-22-2:checked]:opacity-100 motion-reduce:transition-opacity motion-reduce:translate-x-0">
<p class="text-xs tracking-[0.2em] uppercase text-tcar22-acc mb-2.5">Chapter 02</p>
<h3 class="text-[clamp(26px,5vw,44px)] font-extrabold leading-[1.05] tracking-[-0.01em] m-0 [text-shadow:0_2px_20px_oklch(0_0_0/0.5)]">Beyond the shore</h3>
<p class="text-[15px] leading-[1.55] text-tcar22-lead mt-3 max-w-[36ch]">Nothing but horizon, and the sound of the hull.</p>
</div>
</article>
<article class="absolute inset-0 opacity-0 pointer-events-none transition-opacity duration-700 group-has-[#tcar-22-3:checked]:opacity-100 group-has-[#tcar-22-3:checked]:pointer-events-auto">
<img src="https://picsum.photos/seed/plx-3/1200/700" width="1200" height="700" loading="lazy" decoding="async" alt="Alpine ridge" class="absolute inset-0 size-full object-cover scale-[1.12] translate-x-[6%] transition-[scale,translate] duration-1000 ease-[cubic-bezier(0.2,0.8,0.2,1)] group-has-[#tcar-22-3:checked]:scale-[1.06] group-has-[#tcar-22-3:checked]:translate-x-0 motion-reduce:transition-none motion-reduce:scale-100 motion-reduce:translate-x-0">
<div aria-hidden="true" class="absolute inset-0 bg-[linear-gradient(90deg,oklch(0.14_0.01_265/0.82),transparent_65%)]"></div>
<div class="absolute left-0 bottom-0 z-[2] p-[clamp(22px,5vw,52px)] max-w-[70%] text-white -translate-x-[14%] opacity-0 transition-[translate,opacity] duration-[800ms] delay-[120ms] ease-[cubic-bezier(0.2,0.8,0.2,1)] group-has-[#tcar-22-3:checked]:translate-x-0 group-has-[#tcar-22-3:checked]:opacity-100 motion-reduce:transition-opacity motion-reduce:translate-x-0">
<p class="text-xs tracking-[0.2em] uppercase text-tcar22-acc mb-2.5">Chapter 03</p>
<h3 class="text-[clamp(26px,5vw,44px)] font-extrabold leading-[1.05] tracking-[-0.01em] m-0 [text-shadow:0_2px_20px_oklch(0_0_0/0.5)]">Above the clouds</h3>
<p class="text-[15px] leading-[1.55] text-tcar22-lead mt-3 max-w-[36ch]">The last ridge before the summit, and the quiet up there.</p>
</div>
</article>
</div>
<div class="absolute right-[clamp(2px,1.5vw,24px)] bottom-[clamp(2px,1.5vw,24px)] z-[3] flex">
<label for="tcar-22-1" aria-label="Chapter 1" class="group/pip size-11 grid place-items-center cursor-pointer"><span class="size-3 rounded-full bg-tcar22-pip shadow-[0_0_0_1px_oklch(0_0_0/0.35)] transition-[scale,background-color] duration-200 group-hover/pip:bg-tcar22-piphover group-has-[#tcar-22-1:checked]:bg-tcar22-acc group-has-[#tcar-22-1:checked]:scale-[1.3] group-has-[#tcar-22-1:focus-visible]:outline-3 group-has-[#tcar-22-1:focus-visible]:outline-tcar22-acc group-has-[#tcar-22-1:focus-visible]:outline-offset-[3px] motion-reduce:transition-none"></span></label>
<label for="tcar-22-2" aria-label="Chapter 2" class="group/pip size-11 grid place-items-center cursor-pointer"><span class="size-3 rounded-full bg-tcar22-pip shadow-[0_0_0_1px_oklch(0_0_0/0.35)] transition-[scale,background-color] duration-200 group-hover/pip:bg-tcar22-piphover group-has-[#tcar-22-2:checked]:bg-tcar22-acc group-has-[#tcar-22-2:checked]:scale-[1.3] group-has-[#tcar-22-2:focus-visible]:outline-3 group-has-[#tcar-22-2:focus-visible]:outline-tcar22-acc group-has-[#tcar-22-2:focus-visible]:outline-offset-[3px] motion-reduce:transition-none"></span></label>
<label for="tcar-22-3" aria-label="Chapter 3" class="group/pip size-11 grid place-items-center cursor-pointer"><span class="size-3 rounded-full bg-tcar22-pip shadow-[0_0_0_1px_oklch(0_0_0/0.35)] transition-[scale,background-color] duration-200 group-hover/pip:bg-tcar22-piphover group-has-[#tcar-22-3:checked]:bg-tcar22-acc group-has-[#tcar-22-3:checked]:scale-[1.3] group-has-[#tcar-22-3:focus-visible]:outline-3 group-has-[#tcar-22-3:focus-visible]:outline-tcar22-acc group-has-[#tcar-22-3:focus-visible]:outline-offset-[3px] motion-reduce:transition-none"></span></label>
</div>
</div>
</section>
```
## CSS
```css
@import "tailwindcss";
@theme {
--color-tcar22-bg: #0c0d10;
--color-tcar22-bg: oklch(0.16 0.006 265);
--color-tcar22-lead: #dfe2e8;
--color-tcar22-lead: oklch(0.9 0.006 265);
--color-tcar22-pip: #ffffff;
--color-tcar22-pip: oklch(1 0 0 / 0.4);
--color-tcar22-piphover: #ffffff;
--color-tcar22-piphover: oklch(1 0 0 / 0.68);
--color-tcar22-acc: #f5c542;
--color-tcar22-acc: oklch(0.84 0.14 88);
--font-tcar22-sans: 'Archivo', system-ui, sans-serif;
}
.tcar-22 {
width: 100%;
min-height: 100svh;
}
.tcar-22 ::selection {
background: #fff;
color: #111;
}
```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 Parallax Text-Over-Image Story Slider
Source: https://codefronts.com/snippets/tailwind-css-image-carousel/tailwind-parallax-text-over-image-story-slider/
A presentation carousel where, on each transition, the photograph and the headline travel different distances at different speeds. The depth illusion is entirely a mismatch in two numbers, and Tailwind puts both numbers on the elements they move.
## HTML
```html
<section class="tcar-22 w-full min-h-svh grid place-items-center bg-tcar22-bg font-tcar22-sans px-5 py-10" aria-label="Parallax story slider">
<div class="group relative w-[min(760px,100%)]">
<input type="radio" name="tcar-22" id="tcar-22-1" class="sr-only" checked>
<input type="radio" name="tcar-22" id="tcar-22-2" class="sr-only">
<input type="radio" name="tcar-22" id="tcar-22-3" class="sr-only">
<div class="relative aspect-[12/7] rounded-[18px] overflow-hidden shadow-[0_30px_60px_-34px_oklch(0_0_0/0.9)]">
<article class="absolute inset-0 opacity-0 pointer-events-none transition-opacity duration-700 group-has-[#tcar-22-1:checked]:opacity-100 group-has-[#tcar-22-1:checked]:pointer-events-auto">
<img src="https://picsum.photos/seed/plx-1/1200/700" width="1200" height="700" fetchpriority="high" decoding="async" alt="Canyon at sunrise" class="absolute inset-0 size-full object-cover scale-[1.12] translate-x-[6%] transition-[scale,translate] duration-1000 ease-[cubic-bezier(0.2,0.8,0.2,1)] group-has-[#tcar-22-1:checked]:scale-[1.06] group-has-[#tcar-22-1:checked]:translate-x-0 motion-reduce:transition-none motion-reduce:scale-100 motion-reduce:translate-x-0">
<div aria-hidden="true" class="absolute inset-0 bg-[linear-gradient(90deg,oklch(0.14_0.01_265/0.82),transparent_65%)]"></div>
<div class="absolute left-0 bottom-0 z-[2] p-[clamp(22px,5vw,52px)] max-w-[70%] text-white -translate-x-[14%] opacity-0 transition-[translate,opacity] duration-[800ms] delay-[120ms] ease-[cubic-bezier(0.2,0.8,0.2,1)] group-has-[#tcar-22-1:checked]:translate-x-0 group-has-[#tcar-22-1:checked]:opacity-100 motion-reduce:transition-opacity motion-reduce:translate-x-0">
<p class="text-xs tracking-[0.2em] uppercase text-tcar22-acc mb-2.5">Chapter 01</p>
<h3 class="text-[clamp(26px,5vw,44px)] font-extrabold leading-[1.05] tracking-[-0.01em] m-0 [text-shadow:0_2px_20px_oklch(0_0_0/0.5)]">Into the canyon</h3>
<p class="text-[15px] leading-[1.55] text-tcar22-lead mt-3 max-w-[36ch]">Where light carves the rock a little differently every hour.</p>
</div>
</article>
<article class="absolute inset-0 opacity-0 pointer-events-none transition-opacity duration-700 group-has-[#tcar-22-2:checked]:opacity-100 group-has-[#tcar-22-2:checked]:pointer-events-auto">
<img src="https://picsum.photos/seed/plx-2/1200/700" width="1200" height="700" loading="lazy" decoding="async" alt="Open ocean" class="absolute inset-0 size-full object-cover scale-[1.12] translate-x-[6%] transition-[scale,translate] duration-1000 ease-[cubic-bezier(0.2,0.8,0.2,1)] group-has-[#tcar-22-2:checked]:scale-[1.06] group-has-[#tcar-22-2:checked]:translate-x-0 motion-reduce:transition-none motion-reduce:scale-100 motion-reduce:translate-x-0">
<div aria-hidden="true" class="absolute inset-0 bg-[linear-gradient(90deg,oklch(0.14_0.01_265/0.82),transparent_65%)]"></div>
<div class="absolute left-0 bottom-0 z-[2] p-[clamp(22px,5vw,52px)] max-w-[70%] text-white -translate-x-[14%] opacity-0 transition-[translate,opacity] duration-[800ms] delay-[120ms] ease-[cubic-bezier(0.2,0.8,0.2,1)] group-has-[#tcar-22-2:checked]:translate-x-0 group-has-[#tcar-22-2:checked]:opacity-100 motion-reduce:transition-opacity motion-reduce:translate-x-0">
<p class="text-xs tracking-[0.2em] uppercase text-tcar22-acc mb-2.5">Chapter 02</p>
<h3 class="text-[clamp(26px,5vw,44px)] font-extrabold leading-[1.05] tracking-[-0.01em] m-0 [text-shadow:0_2px_20px_oklch(0_0_0/0.5)]">Beyond the shore</h3>
<p class="text-[15px] leading-[1.55] text-tcar22-lead mt-3 max-w-[36ch]">Nothing but horizon, and the sound of the hull.</p>
</div>
</article>
<article class="absolute inset-0 opacity-0 pointer-events-none transition-opacity duration-700 group-has-[#tcar-22-3:checked]:opacity-100 group-has-[#tcar-22-3:checked]:pointer-events-auto">
<img src="https://picsum.photos/seed/plx-3/1200/700" width="1200" height="700" loading="lazy" decoding="async" alt="Alpine ridge" class="absolute inset-0 size-full object-cover scale-[1.12] translate-x-[6%] transition-[scale,translate] duration-1000 ease-[cubic-bezier(0.2,0.8,0.2,1)] group-has-[#tcar-22-3:checked]:scale-[1.06] group-has-[#tcar-22-3:checked]:translate-x-0 motion-reduce:transition-none motion-reduce:scale-100 motion-reduce:translate-x-0">
<div aria-hidden="true" class="absolute inset-0 bg-[linear-gradient(90deg,oklch(0.14_0.01_265/0.82),transparent_65%)]"></div>
<div class="absolute left-0 bottom-0 z-[2] p-[clamp(22px,5vw,52px)] max-w-[70%] text-white -translate-x-[14%] opacity-0 transition-[translate,opacity] duration-[800ms] delay-[120ms] ease-[cubic-bezier(0.2,0.8,0.2,1)] group-has-[#tcar-22-3:checked]:translate-x-0 group-has-[#tcar-22-3:checked]:opacity-100 motion-reduce:transition-opacity motion-reduce:translate-x-0">
<p class="text-xs tracking-[0.2em] uppercase text-tcar22-acc mb-2.5">Chapter 03</p>
<h3 class="text-[clamp(26px,5vw,44px)] font-extrabold leading-[1.05] tracking-[-0.01em] m-0 [text-shadow:0_2px_20px_oklch(0_0_0/0.5)]">Above the clouds</h3>
<p class="text-[15px] leading-[1.55] text-tcar22-lead mt-3 max-w-[36ch]">The last ridge before the summit, and the quiet up there.</p>
</div>
</article>
</div>
<div class="absolute right-[clamp(2px,1.5vw,24px)] bottom-[clamp(2px,1.5vw,24px)] z-[3] flex">
<label for="tcar-22-1" aria-label="Chapter 1" class="group/pip size-11 grid place-items-center cursor-pointer"><span class="size-3 rounded-full bg-tcar22-pip shadow-[0_0_0_1px_oklch(0_0_0/0.35)] transition-[scale,background-color] duration-200 group-hover/pip:bg-tcar22-piphover group-has-[#tcar-22-1:checked]:bg-tcar22-acc group-has-[#tcar-22-1:checked]:scale-[1.3] group-has-[#tcar-22-1:focus-visible]:outline-3 group-has-[#tcar-22-1:focus-visible]:outline-tcar22-acc group-has-[#tcar-22-1:focus-visible]:outline-offset-[3px] motion-reduce:transition-none"></span></label>
<label for="tcar-22-2" aria-label="Chapter 2" class="group/pip size-11 grid place-items-center cursor-pointer"><span class="size-3 rounded-full bg-tcar22-pip shadow-[0_0_0_1px_oklch(0_0_0/0.35)] transition-[scale,background-color] duration-200 group-hover/pip:bg-tcar22-piphover group-has-[#tcar-22-2:checked]:bg-tcar22-acc group-has-[#tcar-22-2:checked]:scale-[1.3] group-has-[#tcar-22-2:focus-visible]:outline-3 group-has-[#tcar-22-2:focus-visible]:outline-tcar22-acc group-has-[#tcar-22-2:focus-visible]:outline-offset-[3px] motion-reduce:transition-none"></span></label>
<label for="tcar-22-3" aria-label="Chapter 3" class="group/pip size-11 grid place-items-center cursor-pointer"><span class="size-3 rounded-full bg-tcar22-pip shadow-[0_0_0_1px_oklch(0_0_0/0.35)] transition-[scale,background-color] duration-200 group-hover/pip:bg-tcar22-piphover group-has-[#tcar-22-3:checked]:bg-tcar22-acc group-has-[#tcar-22-3:checked]:scale-[1.3] group-has-[#tcar-22-3:focus-visible]:outline-3 group-has-[#tcar-22-3:focus-visible]:outline-tcar22-acc group-has-[#tcar-22-3:focus-visible]:outline-offset-[3px] motion-reduce:transition-none"></span></label>
</div>
</div>
</section>
```
## CSS
```css
@import "tailwindcss";
@theme {
--color-tcar22-bg: #0c0d10;
--color-tcar22-bg: oklch(0.16 0.006 265);
--color-tcar22-lead: #dfe2e8;
--color-tcar22-lead: oklch(0.9 0.006 265);
--color-tcar22-pip: #ffffff;
--color-tcar22-pip: oklch(1 0 0 / 0.4);
--color-tcar22-piphover: #ffffff;
--color-tcar22-piphover: oklch(1 0 0 / 0.68);
--color-tcar22-acc: #f5c542;
--color-tcar22-acc: oklch(0.84 0.14 88);
--font-tcar22-sans: 'Archivo', system-ui, sans-serif;
}
.tcar-22 {
width: 100%;
min-height: 100svh;
}
.tcar-22 ::selection {
background: #fff;
color: #111;
}
```How this works
Parallax is a difference, not an effect. The image moves 6% and the text moves 14%, with the text starting 120ms later. Match the two distances and the depth vanishes — which is the single most useful thing to know about this pattern.
Two layers, one condition. Both read the same group-has-[#tcar-22-2:checked]:, so a slide's whole choreography is described by two class lists rather than six selectors.
Reduced motion keeps the fade. Under motion-reduce: both layers sit at their final positions and only opacity changes: still a slideshow, minus the travel.
Make it yours
- Depth: the image vs. text offsets — keep the image's smaller.
- Layer timing: the text's
delay-[120ms]. - A third layer (a kicker with its own offset) deepens the effect.
- Pip colour and scrim:
--color-tcar22-accand the slide overlay.
Gotchas — read before shipping
- The image offset must stay smaller than the text offset. Equal distances read as one flat layer sliding.
- Lock the stage with
aspect-[12/7], or the offsets change the box height mid-transition. - The scrim is what keeps the headline legible over arbitrary photography — do not rely on the images being dark on the left.
- Do not grow a small pip into a 44px target with
before:-inset-4. Atgap-2.5the invisible boxes overlap by 22px and the last pip in the DOM swallows every click aimed at the first two — a control that looks perfect and only works on one of three. Size the <b>label</b> to 44px and centre the dot inside it.
Browser support
| Chrome | Safari | Firefox | Edge |
|---|---|---|---|
| 111+ | 16.4+ | 128+ | 111+ |
Transform and opacity transitions are universal; :has() drives the state map (Chrome 105+, Safari 15.4+, Firefox 121+).