03 / 22
All 22 in 22 Tailwind CSS Image Gallery
- 01Tailwind Hexagon Honeycomb Image Gallery with clip-path
- 02Tailwind Justified Image Gallery with Aspect-Ratio Flex Rows
- 03Tailwind Expanding Panel Image Gallery with Flex-Grow Transitions
- 04Tailwind :has() Hover Spotlight Image Grid
- 05Tailwind Radial Orbit Image Gallery with Counter-Rotating Thumbnails
- 06Tailwind Interactive Pointer Trail Image Gallery
- 07Tailwind Masonry Image Gallery with CSS Columns (No JavaScript)
- 08Tailwind Metro Tile Grid Gallery with Dense Auto-Flow
- 09Tailwind Editorial Magazine Grid Gallery with Blend-Mode Headline
- 10Tailwind Pure CSS Lightbox Gallery with :target (No JavaScript)
- 11Tailwind Filmstrip Carousel Gallery with CSS Scroll-Snap
- 12Tailwind Accordion Image Gallery with Flex-Grow on Hover & Focus
- 13Tailwind Mosaic Grid Gallery with Contained Zoom on Hover
- 14Tailwind Glassmorphism Image Cards with backdrop-blur
- 15Tailwind Diagonal Slice Reveal Gallery with clip-path Halves
- 16Tailwind 3D Tilt Parallax Image Cards with Pointer-Driven Variables
- 17Tailwind 3D Cube Image Viewer with Radio-Driven Rotation
- 18Tailwind 3D Perspective Depth Stack Gallery That Fans on Focus
- 19Tailwind Infinite Scrolling Image Marquee with Seamless Loop
- 20Tailwind Ken Burns Slideshow Gallery with Staggered Cross-Fade
- 21Tailwind Polaroid Photo Stack Gallery with Rotate-on-Hover
- 22Tailwind Scattered Photo Collage with :target Spotlight
Tailwind Expanding Panel Image Gallery with Flex-Grow Transitions
A full-bleed split of tall panels that slide open from flex:1 to flex:5 on hover or keyboard focus, revealing a title, blurb and call-to-action over the photograph. The immersive case-study index, ported so that the open state and the copy reveal are declared on the elements they affect.
Untitled UI Pro: 5,000+ React + Tailwind CSS v4 components · from $349 one-time
Untitled UI React · Affiliate link
The code
<section class="tgl-03 w-full min-h-svh flex items-stretch bg-tgl03-bg font-tgl03-sans" aria-label="Expanding panel gallery">
<div class="flex w-full min-h-svh">
<a href="#" style="--img:url('https://images.unsplash.com/photo-1600210492486-724fe5c67fb0?q=80&w=900&h=1100&auto=format&fit=crop')" class="group relative flex-[1_1_0] min-w-0 overflow-hidden no-underline bg-[image:var(--img)] bg-cover bg-center brightness-[0.62] transition-[flex,filter] duration-[600ms] ease-[cubic-bezier(0.2,0.7,0.2,1)] hover:flex-[5_1_0] hover:brightness-100 focus-within:flex-[5_1_0] focus-within:brightness-100 focus-visible:outline-3 focus-visible:outline-tgl03-acc focus-visible:-outline-offset-[3px] motion-reduce:transition-none">
<span aria-hidden="true" class="absolute inset-0 bg-[linear-gradient(0deg,oklch(0.15_0.02_265/0.85),transparent_60%)]"></span>
<span class="absolute left-0 right-0 top-6 z-[2] text-center text-[11px] font-bold tracking-[0.18em] uppercase text-white/70 transition-opacity duration-300 group-hover:opacity-0 group-focus-within:opacity-0">Structures</span>
<div class="absolute left-0 right-0 bottom-0 z-[2] p-8 max-w-[520px] text-white opacity-0 translate-y-6 transition-[opacity,translate] duration-500 delay-150 group-hover:opacity-100 group-hover:translate-y-0 group-focus-within:opacity-100 group-focus-within:translate-y-0 motion-reduce:transition-none">
<h3 class="text-[30px] font-bold tracking-[-0.01em] m-0">Structures</h3>
<p class="mt-2 text-[15px] leading-[1.5] text-white/85">Concrete, glass and the geometry of modern cities.</p>
<span class="inline-block mt-3.5 text-[13px] font-bold tracking-[0.04em] text-tgl03-acc">View series →</span>
</div>
</a>
<a href="#" style="--img:url('https://images.unsplash.com/photo-1524995997946-a1c2e315a42f?q=80&w=900&h=1100&auto=format&fit=crop')" class="group relative flex-[1_1_0] min-w-0 overflow-hidden no-underline bg-[image:var(--img)] bg-cover bg-center brightness-[0.62] transition-[flex,filter] duration-[600ms] ease-[cubic-bezier(0.2,0.7,0.2,1)] hover:flex-[5_1_0] hover:brightness-100 focus-within:flex-[5_1_0] focus-within:brightness-100 focus-visible:outline-3 focus-visible:outline-tgl03-acc focus-visible:-outline-offset-[3px] motion-reduce:transition-none">
<span aria-hidden="true" class="absolute inset-0 bg-[linear-gradient(0deg,oklch(0.15_0.02_265/0.85),transparent_60%)]"></span>
<span class="absolute left-0 right-0 top-6 z-[2] text-center text-[11px] font-bold tracking-[0.18em] uppercase text-white/70 transition-opacity duration-300 group-hover:opacity-0 group-focus-within:opacity-0">Wilderness</span>
<div class="absolute left-0 right-0 bottom-0 z-[2] p-8 max-w-[520px] text-white opacity-0 translate-y-6 transition-[opacity,translate] duration-500 delay-150 group-hover:opacity-100 group-hover:translate-y-0 group-focus-within:opacity-100 group-focus-within:translate-y-0 motion-reduce:transition-none">
<h3 class="text-[30px] font-bold tracking-[-0.01em] m-0">Wilderness</h3>
<p class="mt-2 text-[15px] leading-[1.5] text-white/85">Remote landscapes far from the nearest road.</p>
<span class="inline-block mt-3.5 text-[13px] font-bold tracking-[0.04em] text-tgl03-acc">View series →</span>
</div>
</a>
<a href="#" style="--img:url('https://images.unsplash.com/photo-1600185365483-26d7a4cc7519?q=80&w=900&h=1100&auto=format&fit=crop')" class="group relative flex-[1_1_0] min-w-0 overflow-hidden no-underline bg-[image:var(--img)] bg-cover bg-center brightness-[0.62] transition-[flex,filter] duration-[600ms] ease-[cubic-bezier(0.2,0.7,0.2,1)] hover:flex-[5_1_0] hover:brightness-100 focus-within:flex-[5_1_0] focus-within:brightness-100 focus-visible:outline-3 focus-visible:outline-tgl03-acc focus-visible:-outline-offset-[3px] motion-reduce:transition-none">
<span aria-hidden="true" class="absolute inset-0 bg-[linear-gradient(0deg,oklch(0.15_0.02_265/0.85),transparent_60%)]"></span>
<span class="absolute left-0 right-0 top-6 z-[2] text-center text-[11px] font-bold tracking-[0.18em] uppercase text-white/70 transition-opacity duration-300 group-hover:opacity-0 group-focus-within:opacity-0">Portraits</span>
<div class="absolute left-0 right-0 bottom-0 z-[2] p-8 max-w-[520px] text-white opacity-0 translate-y-6 transition-[opacity,translate] duration-500 delay-150 group-hover:opacity-100 group-hover:translate-y-0 group-focus-within:opacity-100 group-focus-within:translate-y-0 motion-reduce:transition-none">
<h3 class="text-[30px] font-bold tracking-[-0.01em] m-0">Portraits</h3>
<p class="mt-2 text-[15px] leading-[1.5] text-white/85">Faces and the stories written across them.</p>
<span class="inline-block mt-3.5 text-[13px] font-bold tracking-[0.04em] text-tgl03-acc">View series →</span>
</div>
</a>
<a href="#" style="--img:url('https://images.unsplash.com/photo-1529107386315-e1a2ed48a620?q=80&w=900&h=1100&auto=format&fit=crop')" class="group relative flex-[1_1_0] min-w-0 overflow-hidden no-underline bg-[image:var(--img)] bg-cover bg-center brightness-[0.62] transition-[flex,filter] duration-[600ms] ease-[cubic-bezier(0.2,0.7,0.2,1)] hover:flex-[5_1_0] hover:brightness-100 focus-within:flex-[5_1_0] focus-within:brightness-100 focus-visible:outline-3 focus-visible:outline-tgl03-acc focus-visible:-outline-offset-[3px] motion-reduce:transition-none">
<span aria-hidden="true" class="absolute inset-0 bg-[linear-gradient(0deg,oklch(0.15_0.02_265/0.85),transparent_60%)]"></span>
<span class="absolute left-0 right-0 top-6 z-[2] text-center text-[11px] font-bold tracking-[0.18em] uppercase text-white/70 transition-opacity duration-300 group-hover:opacity-0 group-focus-within:opacity-0">Water</span>
<div class="absolute left-0 right-0 bottom-0 z-[2] p-8 max-w-[520px] text-white opacity-0 translate-y-6 transition-[opacity,translate] duration-500 delay-150 group-hover:opacity-100 group-hover:translate-y-0 group-focus-within:opacity-100 group-focus-within:translate-y-0 motion-reduce:transition-none">
<h3 class="text-[30px] font-bold tracking-[-0.01em] m-0">Water</h3>
<p class="mt-2 text-[15px] leading-[1.5] text-white/85">Oceans, rivers and everything in between.</p>
<span class="inline-block mt-3.5 text-[13px] font-bold tracking-[0.04em] text-tgl03-acc">View series →</span>
</div>
</a>
<a href="#" style="--img:url('https://images.unsplash.com/photo-1486406146926-c627a92ad1ab?q=80&w=900&h=1100&auto=format&fit=crop')" class="group relative flex-[1_1_0] min-w-0 overflow-hidden no-underline bg-[image:var(--img)] bg-cover bg-center brightness-[0.62] transition-[flex,filter] duration-[600ms] ease-[cubic-bezier(0.2,0.7,0.2,1)] hover:flex-[5_1_0] hover:brightness-100 focus-within:flex-[5_1_0] focus-within:brightness-100 focus-visible:outline-3 focus-visible:outline-tgl03-acc focus-visible:-outline-offset-[3px] motion-reduce:transition-none">
<span aria-hidden="true" class="absolute inset-0 bg-[linear-gradient(0deg,oklch(0.15_0.02_265/0.85),transparent_60%)]"></span>
<span class="absolute left-0 right-0 top-6 z-[2] text-center text-[11px] font-bold tracking-[0.18em] uppercase text-white/70 transition-opacity duration-300 group-hover:opacity-0 group-focus-within:opacity-0">After Dark</span>
<div class="absolute left-0 right-0 bottom-0 z-[2] p-8 max-w-[520px] text-white opacity-0 translate-y-6 transition-[opacity,translate] duration-500 delay-150 group-hover:opacity-100 group-hover:translate-y-0 group-focus-within:opacity-100 group-focus-within:translate-y-0 motion-reduce:transition-none">
<h3 class="text-[30px] font-bold tracking-[-0.01em] m-0">After Dark</h3>
<p class="mt-2 text-[15px] leading-[1.5] text-white/85">Long exposures under a moving sky.</p>
<span class="inline-block mt-3.5 text-[13px] font-bold tracking-[0.04em] text-tgl03-acc">View series →</span>
</div>
</a>
</div>
</section><section class="tgl-03 w-full min-h-svh flex items-stretch bg-tgl03-bg font-tgl03-sans" aria-label="Expanding panel gallery">
<div class="flex w-full min-h-svh">
<a href="#" style="--img:url('https://images.unsplash.com/photo-1600210492486-724fe5c67fb0?q=80&w=900&h=1100&auto=format&fit=crop')" class="group relative flex-[1_1_0] min-w-0 overflow-hidden no-underline bg-[image:var(--img)] bg-cover bg-center brightness-[0.62] transition-[flex,filter] duration-[600ms] ease-[cubic-bezier(0.2,0.7,0.2,1)] hover:flex-[5_1_0] hover:brightness-100 focus-within:flex-[5_1_0] focus-within:brightness-100 focus-visible:outline-3 focus-visible:outline-tgl03-acc focus-visible:-outline-offset-[3px] motion-reduce:transition-none">
<span aria-hidden="true" class="absolute inset-0 bg-[linear-gradient(0deg,oklch(0.15_0.02_265/0.85),transparent_60%)]"></span>
<span class="absolute left-0 right-0 top-6 z-[2] text-center text-[11px] font-bold tracking-[0.18em] uppercase text-white/70 transition-opacity duration-300 group-hover:opacity-0 group-focus-within:opacity-0">Structures</span>
<div class="absolute left-0 right-0 bottom-0 z-[2] p-8 max-w-[520px] text-white opacity-0 translate-y-6 transition-[opacity,translate] duration-500 delay-150 group-hover:opacity-100 group-hover:translate-y-0 group-focus-within:opacity-100 group-focus-within:translate-y-0 motion-reduce:transition-none">
<h3 class="text-[30px] font-bold tracking-[-0.01em] m-0">Structures</h3>
<p class="mt-2 text-[15px] leading-[1.5] text-white/85">Concrete, glass and the geometry of modern cities.</p>
<span class="inline-block mt-3.5 text-[13px] font-bold tracking-[0.04em] text-tgl03-acc">View series →</span>
</div>
</a>
<a href="#" style="--img:url('https://images.unsplash.com/photo-1524995997946-a1c2e315a42f?q=80&w=900&h=1100&auto=format&fit=crop')" class="group relative flex-[1_1_0] min-w-0 overflow-hidden no-underline bg-[image:var(--img)] bg-cover bg-center brightness-[0.62] transition-[flex,filter] duration-[600ms] ease-[cubic-bezier(0.2,0.7,0.2,1)] hover:flex-[5_1_0] hover:brightness-100 focus-within:flex-[5_1_0] focus-within:brightness-100 focus-visible:outline-3 focus-visible:outline-tgl03-acc focus-visible:-outline-offset-[3px] motion-reduce:transition-none">
<span aria-hidden="true" class="absolute inset-0 bg-[linear-gradient(0deg,oklch(0.15_0.02_265/0.85),transparent_60%)]"></span>
<span class="absolute left-0 right-0 top-6 z-[2] text-center text-[11px] font-bold tracking-[0.18em] uppercase text-white/70 transition-opacity duration-300 group-hover:opacity-0 group-focus-within:opacity-0">Wilderness</span>
<div class="absolute left-0 right-0 bottom-0 z-[2] p-8 max-w-[520px] text-white opacity-0 translate-y-6 transition-[opacity,translate] duration-500 delay-150 group-hover:opacity-100 group-hover:translate-y-0 group-focus-within:opacity-100 group-focus-within:translate-y-0 motion-reduce:transition-none">
<h3 class="text-[30px] font-bold tracking-[-0.01em] m-0">Wilderness</h3>
<p class="mt-2 text-[15px] leading-[1.5] text-white/85">Remote landscapes far from the nearest road.</p>
<span class="inline-block mt-3.5 text-[13px] font-bold tracking-[0.04em] text-tgl03-acc">View series →</span>
</div>
</a>
<a href="#" style="--img:url('https://images.unsplash.com/photo-1600185365483-26d7a4cc7519?q=80&w=900&h=1100&auto=format&fit=crop')" class="group relative flex-[1_1_0] min-w-0 overflow-hidden no-underline bg-[image:var(--img)] bg-cover bg-center brightness-[0.62] transition-[flex,filter] duration-[600ms] ease-[cubic-bezier(0.2,0.7,0.2,1)] hover:flex-[5_1_0] hover:brightness-100 focus-within:flex-[5_1_0] focus-within:brightness-100 focus-visible:outline-3 focus-visible:outline-tgl03-acc focus-visible:-outline-offset-[3px] motion-reduce:transition-none">
<span aria-hidden="true" class="absolute inset-0 bg-[linear-gradient(0deg,oklch(0.15_0.02_265/0.85),transparent_60%)]"></span>
<span class="absolute left-0 right-0 top-6 z-[2] text-center text-[11px] font-bold tracking-[0.18em] uppercase text-white/70 transition-opacity duration-300 group-hover:opacity-0 group-focus-within:opacity-0">Portraits</span>
<div class="absolute left-0 right-0 bottom-0 z-[2] p-8 max-w-[520px] text-white opacity-0 translate-y-6 transition-[opacity,translate] duration-500 delay-150 group-hover:opacity-100 group-hover:translate-y-0 group-focus-within:opacity-100 group-focus-within:translate-y-0 motion-reduce:transition-none">
<h3 class="text-[30px] font-bold tracking-[-0.01em] m-0">Portraits</h3>
<p class="mt-2 text-[15px] leading-[1.5] text-white/85">Faces and the stories written across them.</p>
<span class="inline-block mt-3.5 text-[13px] font-bold tracking-[0.04em] text-tgl03-acc">View series →</span>
</div>
</a>
<a href="#" style="--img:url('https://images.unsplash.com/photo-1529107386315-e1a2ed48a620?q=80&w=900&h=1100&auto=format&fit=crop')" class="group relative flex-[1_1_0] min-w-0 overflow-hidden no-underline bg-[image:var(--img)] bg-cover bg-center brightness-[0.62] transition-[flex,filter] duration-[600ms] ease-[cubic-bezier(0.2,0.7,0.2,1)] hover:flex-[5_1_0] hover:brightness-100 focus-within:flex-[5_1_0] focus-within:brightness-100 focus-visible:outline-3 focus-visible:outline-tgl03-acc focus-visible:-outline-offset-[3px] motion-reduce:transition-none">
<span aria-hidden="true" class="absolute inset-0 bg-[linear-gradient(0deg,oklch(0.15_0.02_265/0.85),transparent_60%)]"></span>
<span class="absolute left-0 right-0 top-6 z-[2] text-center text-[11px] font-bold tracking-[0.18em] uppercase text-white/70 transition-opacity duration-300 group-hover:opacity-0 group-focus-within:opacity-0">Water</span>
<div class="absolute left-0 right-0 bottom-0 z-[2] p-8 max-w-[520px] text-white opacity-0 translate-y-6 transition-[opacity,translate] duration-500 delay-150 group-hover:opacity-100 group-hover:translate-y-0 group-focus-within:opacity-100 group-focus-within:translate-y-0 motion-reduce:transition-none">
<h3 class="text-[30px] font-bold tracking-[-0.01em] m-0">Water</h3>
<p class="mt-2 text-[15px] leading-[1.5] text-white/85">Oceans, rivers and everything in between.</p>
<span class="inline-block mt-3.5 text-[13px] font-bold tracking-[0.04em] text-tgl03-acc">View series →</span>
</div>
</a>
<a href="#" style="--img:url('https://images.unsplash.com/photo-1486406146926-c627a92ad1ab?q=80&w=900&h=1100&auto=format&fit=crop')" class="group relative flex-[1_1_0] min-w-0 overflow-hidden no-underline bg-[image:var(--img)] bg-cover bg-center brightness-[0.62] transition-[flex,filter] duration-[600ms] ease-[cubic-bezier(0.2,0.7,0.2,1)] hover:flex-[5_1_0] hover:brightness-100 focus-within:flex-[5_1_0] focus-within:brightness-100 focus-visible:outline-3 focus-visible:outline-tgl03-acc focus-visible:-outline-offset-[3px] motion-reduce:transition-none">
<span aria-hidden="true" class="absolute inset-0 bg-[linear-gradient(0deg,oklch(0.15_0.02_265/0.85),transparent_60%)]"></span>
<span class="absolute left-0 right-0 top-6 z-[2] text-center text-[11px] font-bold tracking-[0.18em] uppercase text-white/70 transition-opacity duration-300 group-hover:opacity-0 group-focus-within:opacity-0">After Dark</span>
<div class="absolute left-0 right-0 bottom-0 z-[2] p-8 max-w-[520px] text-white opacity-0 translate-y-6 transition-[opacity,translate] duration-500 delay-150 group-hover:opacity-100 group-hover:translate-y-0 group-focus-within:opacity-100 group-focus-within:translate-y-0 motion-reduce:transition-none">
<h3 class="text-[30px] font-bold tracking-[-0.01em] m-0">After Dark</h3>
<p class="mt-2 text-[15px] leading-[1.5] text-white/85">Long exposures under a moving sky.</p>
<span class="inline-block mt-3.5 text-[13px] font-bold tracking-[0.04em] text-tgl03-acc">View series →</span>
</div>
</a>
</div>
</section>@import "tailwindcss";
@theme {
--color-tgl03-bg: #0c0e12;
--color-tgl03-bg: oklch(0.14 0.012 265);
--color-tgl03-acc: #6fa8ff;
--color-tgl03-acc: oklch(0.75 0.14 250);
--font-tgl03-sans: 'Space Grotesk', system-ui, sans-serif;
}
.tgl-03 {
width: 100%;
min-height: 100svh;
}
.tgl-03 ::selection {
background: var(--color-tgl03-acc);
color: #0c0e12;
}@import "tailwindcss";
@theme {
--color-tgl03-bg: #0c0e12;
--color-tgl03-bg: oklch(0.14 0.012 265);
--color-tgl03-acc: #6fa8ff;
--color-tgl03-acc: oklch(0.75 0.14 250);
--font-tgl03-sans: 'Space Grotesk', system-ui, sans-serif;
}
.tgl-03 {
width: 100%;
min-height: 100svh;
}
.tgl-03 ::selection {
background: var(--color-tgl03-acc);
color: #0c0e12;
}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-tgl03-bg: #0c0e12;
--color-tgl03-bg: oklch(0.14 0.012 265);
--color-tgl03-acc: #6fa8ff;
--color-tgl03-acc: oklch(0.75 0.14 250);
--font-tgl03-sans: 'Space Grotesk', system-ui, sans-serif;
}
.tgl-03 {
width: 100%;
min-height: 100svh;
}
.tgl-03 ::selection {
background: var(--color-tgl03-acc);
color: #0c0e12;
}@import "tailwindcss";
@theme {
--color-tgl03-bg: #0c0e12;
--color-tgl03-bg: oklch(0.14 0.012 265);
--color-tgl03-acc: #6fa8ff;
--color-tgl03-acc: oklch(0.75 0.14 250);
--font-tgl03-sans: 'Space Grotesk', system-ui, sans-serif;
}
.tgl-03 {
width: 100%;
min-height: 100svh;
}
.tgl-03 ::selection {
background: var(--color-tgl03-acc);
color: #0c0e12;
}<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&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&display=swap">What changed in the port
Which parts became utilities, which stayed CSS, and why.
hover:andfocus-within:sit adjacent in the class list, which is the strongest argument for the port: the keyboard path is now impossible to overlook.- The resting dim moved from a stacked overlay to
brightness-[0.62], one utility that also animates on the compositor. - UI change from the CSS original: collapsed panels now carry a small vertical label that fades out as the panel opens. The original showed five unlabelled photographs, so nothing told a touch user what they were about to open.
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 Expanding Panel Image Gallery with Flex-Grow Transitions
Source: https://codefronts.com/snippets/tailwind-css-image-gallery/tailwind-expanding-panel-image-gallery-flex-grow/
A full-bleed split of tall panels that slide open from flex:1 to flex:5 on hover or keyboard focus, revealing a title, blurb and call-to-action over the photograph. The immersive case-study index, ported so that the open state and the copy reveal are declared on the elements they affect.
## HTML
```html
<section class="tgl-03 w-full min-h-svh flex items-stretch bg-tgl03-bg font-tgl03-sans" aria-label="Expanding panel gallery">
<div class="flex w-full min-h-svh">
<a href="#" style="--img:url('https://images.unsplash.com/photo-1600210492486-724fe5c67fb0?q=80&w=900&h=1100&auto=format&fit=crop')" class="group relative flex-[1_1_0] min-w-0 overflow-hidden no-underline bg-[image:var(--img)] bg-cover bg-center brightness-[0.62] transition-[flex,filter] duration-[600ms] ease-[cubic-bezier(0.2,0.7,0.2,1)] hover:flex-[5_1_0] hover:brightness-100 focus-within:flex-[5_1_0] focus-within:brightness-100 focus-visible:outline-3 focus-visible:outline-tgl03-acc focus-visible:-outline-offset-[3px] motion-reduce:transition-none">
<span aria-hidden="true" class="absolute inset-0 bg-[linear-gradient(0deg,oklch(0.15_0.02_265/0.85),transparent_60%)]"></span>
<span class="absolute left-0 right-0 top-6 z-[2] text-center text-[11px] font-bold tracking-[0.18em] uppercase text-white/70 transition-opacity duration-300 group-hover:opacity-0 group-focus-within:opacity-0">Structures</span>
<div class="absolute left-0 right-0 bottom-0 z-[2] p-8 max-w-[520px] text-white opacity-0 translate-y-6 transition-[opacity,translate] duration-500 delay-150 group-hover:opacity-100 group-hover:translate-y-0 group-focus-within:opacity-100 group-focus-within:translate-y-0 motion-reduce:transition-none">
<h3 class="text-[30px] font-bold tracking-[-0.01em] m-0">Structures</h3>
<p class="mt-2 text-[15px] leading-[1.5] text-white/85">Concrete, glass and the geometry of modern cities.</p>
<span class="inline-block mt-3.5 text-[13px] font-bold tracking-[0.04em] text-tgl03-acc">View series →</span>
</div>
</a>
<a href="#" style="--img:url('https://images.unsplash.com/photo-1524995997946-a1c2e315a42f?q=80&w=900&h=1100&auto=format&fit=crop')" class="group relative flex-[1_1_0] min-w-0 overflow-hidden no-underline bg-[image:var(--img)] bg-cover bg-center brightness-[0.62] transition-[flex,filter] duration-[600ms] ease-[cubic-bezier(0.2,0.7,0.2,1)] hover:flex-[5_1_0] hover:brightness-100 focus-within:flex-[5_1_0] focus-within:brightness-100 focus-visible:outline-3 focus-visible:outline-tgl03-acc focus-visible:-outline-offset-[3px] motion-reduce:transition-none">
<span aria-hidden="true" class="absolute inset-0 bg-[linear-gradient(0deg,oklch(0.15_0.02_265/0.85),transparent_60%)]"></span>
<span class="absolute left-0 right-0 top-6 z-[2] text-center text-[11px] font-bold tracking-[0.18em] uppercase text-white/70 transition-opacity duration-300 group-hover:opacity-0 group-focus-within:opacity-0">Wilderness</span>
<div class="absolute left-0 right-0 bottom-0 z-[2] p-8 max-w-[520px] text-white opacity-0 translate-y-6 transition-[opacity,translate] duration-500 delay-150 group-hover:opacity-100 group-hover:translate-y-0 group-focus-within:opacity-100 group-focus-within:translate-y-0 motion-reduce:transition-none">
<h3 class="text-[30px] font-bold tracking-[-0.01em] m-0">Wilderness</h3>
<p class="mt-2 text-[15px] leading-[1.5] text-white/85">Remote landscapes far from the nearest road.</p>
<span class="inline-block mt-3.5 text-[13px] font-bold tracking-[0.04em] text-tgl03-acc">View series →</span>
</div>
</a>
<a href="#" style="--img:url('https://images.unsplash.com/photo-1600185365483-26d7a4cc7519?q=80&w=900&h=1100&auto=format&fit=crop')" class="group relative flex-[1_1_0] min-w-0 overflow-hidden no-underline bg-[image:var(--img)] bg-cover bg-center brightness-[0.62] transition-[flex,filter] duration-[600ms] ease-[cubic-bezier(0.2,0.7,0.2,1)] hover:flex-[5_1_0] hover:brightness-100 focus-within:flex-[5_1_0] focus-within:brightness-100 focus-visible:outline-3 focus-visible:outline-tgl03-acc focus-visible:-outline-offset-[3px] motion-reduce:transition-none">
<span aria-hidden="true" class="absolute inset-0 bg-[linear-gradient(0deg,oklch(0.15_0.02_265/0.85),transparent_60%)]"></span>
<span class="absolute left-0 right-0 top-6 z-[2] text-center text-[11px] font-bold tracking-[0.18em] uppercase text-white/70 transition-opacity duration-300 group-hover:opacity-0 group-focus-within:opacity-0">Portraits</span>
<div class="absolute left-0 right-0 bottom-0 z-[2] p-8 max-w-[520px] text-white opacity-0 translate-y-6 transition-[opacity,translate] duration-500 delay-150 group-hover:opacity-100 group-hover:translate-y-0 group-focus-within:opacity-100 group-focus-within:translate-y-0 motion-reduce:transition-none">
<h3 class="text-[30px] font-bold tracking-[-0.01em] m-0">Portraits</h3>
<p class="mt-2 text-[15px] leading-[1.5] text-white/85">Faces and the stories written across them.</p>
<span class="inline-block mt-3.5 text-[13px] font-bold tracking-[0.04em] text-tgl03-acc">View series →</span>
</div>
</a>
<a href="#" style="--img:url('https://images.unsplash.com/photo-1529107386315-e1a2ed48a620?q=80&w=900&h=1100&auto=format&fit=crop')" class="group relative flex-[1_1_0] min-w-0 overflow-hidden no-underline bg-[image:var(--img)] bg-cover bg-center brightness-[0.62] transition-[flex,filter] duration-[600ms] ease-[cubic-bezier(0.2,0.7,0.2,1)] hover:flex-[5_1_0] hover:brightness-100 focus-within:flex-[5_1_0] focus-within:brightness-100 focus-visible:outline-3 focus-visible:outline-tgl03-acc focus-visible:-outline-offset-[3px] motion-reduce:transition-none">
<span aria-hidden="true" class="absolute inset-0 bg-[linear-gradient(0deg,oklch(0.15_0.02_265/0.85),transparent_60%)]"></span>
<span class="absolute left-0 right-0 top-6 z-[2] text-center text-[11px] font-bold tracking-[0.18em] uppercase text-white/70 transition-opacity duration-300 group-hover:opacity-0 group-focus-within:opacity-0">Water</span>
<div class="absolute left-0 right-0 bottom-0 z-[2] p-8 max-w-[520px] text-white opacity-0 translate-y-6 transition-[opacity,translate] duration-500 delay-150 group-hover:opacity-100 group-hover:translate-y-0 group-focus-within:opacity-100 group-focus-within:translate-y-0 motion-reduce:transition-none">
<h3 class="text-[30px] font-bold tracking-[-0.01em] m-0">Water</h3>
<p class="mt-2 text-[15px] leading-[1.5] text-white/85">Oceans, rivers and everything in between.</p>
<span class="inline-block mt-3.5 text-[13px] font-bold tracking-[0.04em] text-tgl03-acc">View series →</span>
</div>
</a>
<a href="#" style="--img:url('https://images.unsplash.com/photo-1486406146926-c627a92ad1ab?q=80&w=900&h=1100&auto=format&fit=crop')" class="group relative flex-[1_1_0] min-w-0 overflow-hidden no-underline bg-[image:var(--img)] bg-cover bg-center brightness-[0.62] transition-[flex,filter] duration-[600ms] ease-[cubic-bezier(0.2,0.7,0.2,1)] hover:flex-[5_1_0] hover:brightness-100 focus-within:flex-[5_1_0] focus-within:brightness-100 focus-visible:outline-3 focus-visible:outline-tgl03-acc focus-visible:-outline-offset-[3px] motion-reduce:transition-none">
<span aria-hidden="true" class="absolute inset-0 bg-[linear-gradient(0deg,oklch(0.15_0.02_265/0.85),transparent_60%)]"></span>
<span class="absolute left-0 right-0 top-6 z-[2] text-center text-[11px] font-bold tracking-[0.18em] uppercase text-white/70 transition-opacity duration-300 group-hover:opacity-0 group-focus-within:opacity-0">After Dark</span>
<div class="absolute left-0 right-0 bottom-0 z-[2] p-8 max-w-[520px] text-white opacity-0 translate-y-6 transition-[opacity,translate] duration-500 delay-150 group-hover:opacity-100 group-hover:translate-y-0 group-focus-within:opacity-100 group-focus-within:translate-y-0 motion-reduce:transition-none">
<h3 class="text-[30px] font-bold tracking-[-0.01em] m-0">After Dark</h3>
<p class="mt-2 text-[15px] leading-[1.5] text-white/85">Long exposures under a moving sky.</p>
<span class="inline-block mt-3.5 text-[13px] font-bold tracking-[0.04em] text-tgl03-acc">View series →</span>
</div>
</a>
</div>
</section>
```
## CSS
```css
@import "tailwindcss";
@theme {
--color-tgl03-bg: #0c0e12;
--color-tgl03-bg: oklch(0.14 0.012 265);
--color-tgl03-acc: #6fa8ff;
--color-tgl03-acc: oklch(0.75 0.14 250);
--font-tgl03-sans: 'Space Grotesk', system-ui, sans-serif;
}
.tgl-03 {
width: 100%;
min-height: 100svh;
}
.tgl-03 ::selection {
background: var(--color-tgl03-acc);
color: #0c0e12;
}
```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 Expanding Panel Image Gallery with Flex-Grow Transitions
Source: https://codefronts.com/snippets/tailwind-css-image-gallery/tailwind-expanding-panel-image-gallery-flex-grow/
A full-bleed split of tall panels that slide open from flex:1 to flex:5 on hover or keyboard focus, revealing a title, blurb and call-to-action over the photograph. The immersive case-study index, ported so that the open state and the copy reveal are declared on the elements they affect.
## HTML
```html
<section class="tgl-03 w-full min-h-svh flex items-stretch bg-tgl03-bg font-tgl03-sans" aria-label="Expanding panel gallery">
<div class="flex w-full min-h-svh">
<a href="#" style="--img:url('https://images.unsplash.com/photo-1600210492486-724fe5c67fb0?q=80&w=900&h=1100&auto=format&fit=crop')" class="group relative flex-[1_1_0] min-w-0 overflow-hidden no-underline bg-[image:var(--img)] bg-cover bg-center brightness-[0.62] transition-[flex,filter] duration-[600ms] ease-[cubic-bezier(0.2,0.7,0.2,1)] hover:flex-[5_1_0] hover:brightness-100 focus-within:flex-[5_1_0] focus-within:brightness-100 focus-visible:outline-3 focus-visible:outline-tgl03-acc focus-visible:-outline-offset-[3px] motion-reduce:transition-none">
<span aria-hidden="true" class="absolute inset-0 bg-[linear-gradient(0deg,oklch(0.15_0.02_265/0.85),transparent_60%)]"></span>
<span class="absolute left-0 right-0 top-6 z-[2] text-center text-[11px] font-bold tracking-[0.18em] uppercase text-white/70 transition-opacity duration-300 group-hover:opacity-0 group-focus-within:opacity-0">Structures</span>
<div class="absolute left-0 right-0 bottom-0 z-[2] p-8 max-w-[520px] text-white opacity-0 translate-y-6 transition-[opacity,translate] duration-500 delay-150 group-hover:opacity-100 group-hover:translate-y-0 group-focus-within:opacity-100 group-focus-within:translate-y-0 motion-reduce:transition-none">
<h3 class="text-[30px] font-bold tracking-[-0.01em] m-0">Structures</h3>
<p class="mt-2 text-[15px] leading-[1.5] text-white/85">Concrete, glass and the geometry of modern cities.</p>
<span class="inline-block mt-3.5 text-[13px] font-bold tracking-[0.04em] text-tgl03-acc">View series →</span>
</div>
</a>
<a href="#" style="--img:url('https://images.unsplash.com/photo-1524995997946-a1c2e315a42f?q=80&w=900&h=1100&auto=format&fit=crop')" class="group relative flex-[1_1_0] min-w-0 overflow-hidden no-underline bg-[image:var(--img)] bg-cover bg-center brightness-[0.62] transition-[flex,filter] duration-[600ms] ease-[cubic-bezier(0.2,0.7,0.2,1)] hover:flex-[5_1_0] hover:brightness-100 focus-within:flex-[5_1_0] focus-within:brightness-100 focus-visible:outline-3 focus-visible:outline-tgl03-acc focus-visible:-outline-offset-[3px] motion-reduce:transition-none">
<span aria-hidden="true" class="absolute inset-0 bg-[linear-gradient(0deg,oklch(0.15_0.02_265/0.85),transparent_60%)]"></span>
<span class="absolute left-0 right-0 top-6 z-[2] text-center text-[11px] font-bold tracking-[0.18em] uppercase text-white/70 transition-opacity duration-300 group-hover:opacity-0 group-focus-within:opacity-0">Wilderness</span>
<div class="absolute left-0 right-0 bottom-0 z-[2] p-8 max-w-[520px] text-white opacity-0 translate-y-6 transition-[opacity,translate] duration-500 delay-150 group-hover:opacity-100 group-hover:translate-y-0 group-focus-within:opacity-100 group-focus-within:translate-y-0 motion-reduce:transition-none">
<h3 class="text-[30px] font-bold tracking-[-0.01em] m-0">Wilderness</h3>
<p class="mt-2 text-[15px] leading-[1.5] text-white/85">Remote landscapes far from the nearest road.</p>
<span class="inline-block mt-3.5 text-[13px] font-bold tracking-[0.04em] text-tgl03-acc">View series →</span>
</div>
</a>
<a href="#" style="--img:url('https://images.unsplash.com/photo-1600185365483-26d7a4cc7519?q=80&w=900&h=1100&auto=format&fit=crop')" class="group relative flex-[1_1_0] min-w-0 overflow-hidden no-underline bg-[image:var(--img)] bg-cover bg-center brightness-[0.62] transition-[flex,filter] duration-[600ms] ease-[cubic-bezier(0.2,0.7,0.2,1)] hover:flex-[5_1_0] hover:brightness-100 focus-within:flex-[5_1_0] focus-within:brightness-100 focus-visible:outline-3 focus-visible:outline-tgl03-acc focus-visible:-outline-offset-[3px] motion-reduce:transition-none">
<span aria-hidden="true" class="absolute inset-0 bg-[linear-gradient(0deg,oklch(0.15_0.02_265/0.85),transparent_60%)]"></span>
<span class="absolute left-0 right-0 top-6 z-[2] text-center text-[11px] font-bold tracking-[0.18em] uppercase text-white/70 transition-opacity duration-300 group-hover:opacity-0 group-focus-within:opacity-0">Portraits</span>
<div class="absolute left-0 right-0 bottom-0 z-[2] p-8 max-w-[520px] text-white opacity-0 translate-y-6 transition-[opacity,translate] duration-500 delay-150 group-hover:opacity-100 group-hover:translate-y-0 group-focus-within:opacity-100 group-focus-within:translate-y-0 motion-reduce:transition-none">
<h3 class="text-[30px] font-bold tracking-[-0.01em] m-0">Portraits</h3>
<p class="mt-2 text-[15px] leading-[1.5] text-white/85">Faces and the stories written across them.</p>
<span class="inline-block mt-3.5 text-[13px] font-bold tracking-[0.04em] text-tgl03-acc">View series →</span>
</div>
</a>
<a href="#" style="--img:url('https://images.unsplash.com/photo-1529107386315-e1a2ed48a620?q=80&w=900&h=1100&auto=format&fit=crop')" class="group relative flex-[1_1_0] min-w-0 overflow-hidden no-underline bg-[image:var(--img)] bg-cover bg-center brightness-[0.62] transition-[flex,filter] duration-[600ms] ease-[cubic-bezier(0.2,0.7,0.2,1)] hover:flex-[5_1_0] hover:brightness-100 focus-within:flex-[5_1_0] focus-within:brightness-100 focus-visible:outline-3 focus-visible:outline-tgl03-acc focus-visible:-outline-offset-[3px] motion-reduce:transition-none">
<span aria-hidden="true" class="absolute inset-0 bg-[linear-gradient(0deg,oklch(0.15_0.02_265/0.85),transparent_60%)]"></span>
<span class="absolute left-0 right-0 top-6 z-[2] text-center text-[11px] font-bold tracking-[0.18em] uppercase text-white/70 transition-opacity duration-300 group-hover:opacity-0 group-focus-within:opacity-0">Water</span>
<div class="absolute left-0 right-0 bottom-0 z-[2] p-8 max-w-[520px] text-white opacity-0 translate-y-6 transition-[opacity,translate] duration-500 delay-150 group-hover:opacity-100 group-hover:translate-y-0 group-focus-within:opacity-100 group-focus-within:translate-y-0 motion-reduce:transition-none">
<h3 class="text-[30px] font-bold tracking-[-0.01em] m-0">Water</h3>
<p class="mt-2 text-[15px] leading-[1.5] text-white/85">Oceans, rivers and everything in between.</p>
<span class="inline-block mt-3.5 text-[13px] font-bold tracking-[0.04em] text-tgl03-acc">View series →</span>
</div>
</a>
<a href="#" style="--img:url('https://images.unsplash.com/photo-1486406146926-c627a92ad1ab?q=80&w=900&h=1100&auto=format&fit=crop')" class="group relative flex-[1_1_0] min-w-0 overflow-hidden no-underline bg-[image:var(--img)] bg-cover bg-center brightness-[0.62] transition-[flex,filter] duration-[600ms] ease-[cubic-bezier(0.2,0.7,0.2,1)] hover:flex-[5_1_0] hover:brightness-100 focus-within:flex-[5_1_0] focus-within:brightness-100 focus-visible:outline-3 focus-visible:outline-tgl03-acc focus-visible:-outline-offset-[3px] motion-reduce:transition-none">
<span aria-hidden="true" class="absolute inset-0 bg-[linear-gradient(0deg,oklch(0.15_0.02_265/0.85),transparent_60%)]"></span>
<span class="absolute left-0 right-0 top-6 z-[2] text-center text-[11px] font-bold tracking-[0.18em] uppercase text-white/70 transition-opacity duration-300 group-hover:opacity-0 group-focus-within:opacity-0">After Dark</span>
<div class="absolute left-0 right-0 bottom-0 z-[2] p-8 max-w-[520px] text-white opacity-0 translate-y-6 transition-[opacity,translate] duration-500 delay-150 group-hover:opacity-100 group-hover:translate-y-0 group-focus-within:opacity-100 group-focus-within:translate-y-0 motion-reduce:transition-none">
<h3 class="text-[30px] font-bold tracking-[-0.01em] m-0">After Dark</h3>
<p class="mt-2 text-[15px] leading-[1.5] text-white/85">Long exposures under a moving sky.</p>
<span class="inline-block mt-3.5 text-[13px] font-bold tracking-[0.04em] text-tgl03-acc">View series →</span>
</div>
</a>
</div>
</section>
```
## CSS
```css
@import "tailwindcss";
@theme {
--color-tgl03-bg: #0c0e12;
--color-tgl03-bg: oklch(0.14 0.012 265);
--color-tgl03-acc: #6fa8ff;
--color-tgl03-acc: oklch(0.75 0.14 250);
--font-tgl03-sans: 'Space Grotesk', system-ui, sans-serif;
}
.tgl-03 {
width: 100%;
min-height: 100svh;
}
.tgl-03 ::selection {
background: var(--color-tgl03-acc);
color: #0c0e12;
}
```How this works
The open state is two utilities. Five panels share the row at flex-[1_1_0]; the interacted one jumps to flex-[5_1_0] and the rest absorb the loss. Stating hover: and focus-within: side by side is the port's quiet accessibility win — in CSS they were a comma-joined selector far from the panel, and the second half is exactly the half that gets dropped in a refactor.
The copy reveal is a group, delayed. The panel is group; the inner block carries opacity-0 translate-y-6 at rest and group-hover:/group-focus-within: the opposite, with delay-150 so the text does not race the width.
Collapsed panels keep a vertical label, so the row still reads as five destinations before anything is hovered — the original left them blank.
Make it yours
- Dominance:
hover:flex-[5_1_0]is bold,hover:flex-[3_1_0]gentle. - Flip to horizontal bands with
flex-colon the row and the same grow utilities. - Change the reveal pacing with
delay-150/duration-500on the inner block.
Gotchas — read before shipping
- Animating
flexanimates layout — it is the technique here, but keep the panel count at five or six and the easing short. focus-within:must be present on the panel, not justhover:, or keyboard users open a panel they cannot read.- Give collapsed panels enough width to stay tappable on touch, where there is no hover at all.
Browser support
| Chrome | Safari | Firefox | Edge |
|---|---|---|---|
| 111+ | 16.4+ | 128+ | 111+ |
Flexbox and :focus-within are universal; the floor is Tailwind v4's generated sheet.