12 / 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 Accordion Image Gallery with Flex-Grow on Hover & Focus
A compact row of vertical image strips that expand on hover or keyboard focus while their neighbours shrink. Every panel is a real <button>, so the accordion opens on focus exactly as it does on hover — the port states both on the same element, one class apart.
Untitled UI Pro: 5,000+ React + Tailwind CSS v4 components · from $349 one-time
Untitled UI React · Affiliate link
The code
<section class="tgl-12 w-full min-h-svh grid place-items-center bg-tgl12-bg font-tgl12-sans px-5 py-10" aria-label="Accordion image gallery">
<div class="flex gap-2 w-[min(880px,100%)] h-[min(440px,60vh)]">
<button type="button" style="--img:url('https://images.unsplash.com/photo-1531297484001-80022131f5a1?q=80&w=700&h=900&auto=format&fit=crop')" class="group relative flex-1 min-w-0 p-0 border-0 cursor-pointer rounded-xl overflow-hidden bg-[image:var(--img)] bg-cover bg-center brightness-[0.72] saturate-[0.95] transition-[flex-grow,filter] duration-500 ease-[cubic-bezier(0.2,0.7,0.2,1)] hover:grow-[4] hover:brightness-100 hover:saturate-[1.05] focus:grow-[4] focus:brightness-100 focus-visible:outline-3 focus-visible:outline-tgl12-acc focus-visible:-outline-offset-[3px] motion-reduce:transition-none">
<span aria-hidden="true" class="absolute inset-0 bg-[linear-gradient(0deg,rgba(10,6,4,0.7),transparent_55%)]"></span>
<span class="absolute right-3 top-4 z-[2] text-white text-[15px] font-bold tracking-[0.06em] [writing-mode:vertical-rl] rotate-180 [text-shadow:0_1px_4px_rgba(0,0,0,0.7)] transition-all duration-300 group-hover:[writing-mode:horizontal-tb] group-hover:rotate-0 group-hover:inset-x-0 group-hover:top-auto group-hover:bottom-4 group-hover:text-lg group-focus:[writing-mode:horizontal-tb] group-focus:rotate-0 group-focus:inset-x-0 group-focus:top-auto group-focus:bottom-4 group-focus:text-lg">Peaks</span>
</button>
<button type="button" style="--img:url('https://images.unsplash.com/photo-1522199755839-a2bacb67c546?q=80&w=700&h=900&auto=format&fit=crop')" class="group relative flex-1 min-w-0 p-0 border-0 cursor-pointer rounded-xl overflow-hidden bg-[image:var(--img)] bg-cover bg-center brightness-[0.72] saturate-[0.95] transition-[flex-grow,filter] duration-500 ease-[cubic-bezier(0.2,0.7,0.2,1)] hover:grow-[4] hover:brightness-100 hover:saturate-[1.05] focus:grow-[4] focus:brightness-100 focus-visible:outline-3 focus-visible:outline-tgl12-acc focus-visible:-outline-offset-[3px] motion-reduce:transition-none">
<span aria-hidden="true" class="absolute inset-0 bg-[linear-gradient(0deg,rgba(10,6,4,0.7),transparent_55%)]"></span>
<span class="absolute right-3 top-4 z-[2] text-white text-[15px] font-bold tracking-[0.06em] [writing-mode:vertical-rl] rotate-180 [text-shadow:0_1px_4px_rgba(0,0,0,0.7)] transition-all duration-300 group-hover:[writing-mode:horizontal-tb] group-hover:rotate-0 group-hover:inset-x-0 group-hover:top-auto group-hover:bottom-4 group-hover:text-lg group-focus:[writing-mode:horizontal-tb] group-focus:rotate-0 group-focus:inset-x-0 group-focus:top-auto group-focus:bottom-4 group-focus:text-lg">Forests</span>
</button>
<button type="button" style="--img:url('https://images.unsplash.com/photo-1615663245857-ac93bb7c39e7?q=80&w=700&h=900&auto=format&fit=crop')" class="group relative flex-1 min-w-0 p-0 border-0 cursor-pointer rounded-xl overflow-hidden bg-[image:var(--img)] bg-cover bg-center brightness-[0.72] saturate-[0.95] transition-[flex-grow,filter] duration-500 ease-[cubic-bezier(0.2,0.7,0.2,1)] hover:grow-[4] hover:brightness-100 hover:saturate-[1.05] focus:grow-[4] focus:brightness-100 focus-visible:outline-3 focus-visible:outline-tgl12-acc focus-visible:-outline-offset-[3px] motion-reduce:transition-none">
<span aria-hidden="true" class="absolute inset-0 bg-[linear-gradient(0deg,rgba(10,6,4,0.7),transparent_55%)]"></span>
<span class="absolute right-3 top-4 z-[2] text-white text-[15px] font-bold tracking-[0.06em] [writing-mode:vertical-rl] rotate-180 [text-shadow:0_1px_4px_rgba(0,0,0,0.7)] transition-all duration-300 group-hover:[writing-mode:horizontal-tb] group-hover:rotate-0 group-hover:inset-x-0 group-hover:top-auto group-hover:bottom-4 group-hover:text-lg group-focus:[writing-mode:horizontal-tb] group-focus:rotate-0 group-focus:inset-x-0 group-focus:top-auto group-focus:bottom-4 group-focus:text-lg">Coast</span>
</button>
<button type="button" style="--img:url('https://images.unsplash.com/photo-1516035069371-29a1b244cc32?q=80&w=700&h=900&auto=format&fit=crop')" class="group relative flex-1 min-w-0 p-0 border-0 cursor-pointer rounded-xl overflow-hidden bg-[image:var(--img)] bg-cover bg-center brightness-[0.72] saturate-[0.95] transition-[flex-grow,filter] duration-500 ease-[cubic-bezier(0.2,0.7,0.2,1)] hover:grow-[4] hover:brightness-100 hover:saturate-[1.05] focus:grow-[4] focus:brightness-100 focus-visible:outline-3 focus-visible:outline-tgl12-acc focus-visible:-outline-offset-[3px] motion-reduce:transition-none">
<span aria-hidden="true" class="absolute inset-0 bg-[linear-gradient(0deg,rgba(10,6,4,0.7),transparent_55%)]"></span>
<span class="absolute right-3 top-4 z-[2] text-white text-[15px] font-bold tracking-[0.06em] [writing-mode:vertical-rl] rotate-180 [text-shadow:0_1px_4px_rgba(0,0,0,0.7)] transition-all duration-300 group-hover:[writing-mode:horizontal-tb] group-hover:rotate-0 group-hover:inset-x-0 group-hover:top-auto group-hover:bottom-4 group-hover:text-lg group-focus:[writing-mode:horizontal-tb] group-focus:rotate-0 group-focus:inset-x-0 group-focus:top-auto group-focus:bottom-4 group-focus:text-lg">Desert</span>
</button>
<button type="button" style="--img:url('https://images.unsplash.com/photo-1535632066927-ab7c9ab60908?q=80&w=700&h=900&auto=format&fit=crop')" class="group relative flex-1 min-w-0 p-0 border-0 cursor-pointer rounded-xl overflow-hidden bg-[image:var(--img)] bg-cover bg-center brightness-[0.72] saturate-[0.95] transition-[flex-grow,filter] duration-500 ease-[cubic-bezier(0.2,0.7,0.2,1)] hover:grow-[4] hover:brightness-100 hover:saturate-[1.05] focus:grow-[4] focus:brightness-100 focus-visible:outline-3 focus-visible:outline-tgl12-acc focus-visible:-outline-offset-[3px] motion-reduce:transition-none">
<span aria-hidden="true" class="absolute inset-0 bg-[linear-gradient(0deg,rgba(10,6,4,0.7),transparent_55%)]"></span>
<span class="absolute right-3 top-4 z-[2] text-white text-[15px] font-bold tracking-[0.06em] [writing-mode:vertical-rl] rotate-180 [text-shadow:0_1px_4px_rgba(0,0,0,0.7)] transition-all duration-300 group-hover:[writing-mode:horizontal-tb] group-hover:rotate-0 group-hover:inset-x-0 group-hover:top-auto group-hover:bottom-4 group-hover:text-lg group-focus:[writing-mode:horizontal-tb] group-focus:rotate-0 group-focus:inset-x-0 group-focus:top-auto group-focus:bottom-4 group-focus:text-lg">Cities</span>
</button>
</div>
</section><section class="tgl-12 w-full min-h-svh grid place-items-center bg-tgl12-bg font-tgl12-sans px-5 py-10" aria-label="Accordion image gallery">
<div class="flex gap-2 w-[min(880px,100%)] h-[min(440px,60vh)]">
<button type="button" style="--img:url('https://images.unsplash.com/photo-1531297484001-80022131f5a1?q=80&w=700&h=900&auto=format&fit=crop')" class="group relative flex-1 min-w-0 p-0 border-0 cursor-pointer rounded-xl overflow-hidden bg-[image:var(--img)] bg-cover bg-center brightness-[0.72] saturate-[0.95] transition-[flex-grow,filter] duration-500 ease-[cubic-bezier(0.2,0.7,0.2,1)] hover:grow-[4] hover:brightness-100 hover:saturate-[1.05] focus:grow-[4] focus:brightness-100 focus-visible:outline-3 focus-visible:outline-tgl12-acc focus-visible:-outline-offset-[3px] motion-reduce:transition-none">
<span aria-hidden="true" class="absolute inset-0 bg-[linear-gradient(0deg,rgba(10,6,4,0.7),transparent_55%)]"></span>
<span class="absolute right-3 top-4 z-[2] text-white text-[15px] font-bold tracking-[0.06em] [writing-mode:vertical-rl] rotate-180 [text-shadow:0_1px_4px_rgba(0,0,0,0.7)] transition-all duration-300 group-hover:[writing-mode:horizontal-tb] group-hover:rotate-0 group-hover:inset-x-0 group-hover:top-auto group-hover:bottom-4 group-hover:text-lg group-focus:[writing-mode:horizontal-tb] group-focus:rotate-0 group-focus:inset-x-0 group-focus:top-auto group-focus:bottom-4 group-focus:text-lg">Peaks</span>
</button>
<button type="button" style="--img:url('https://images.unsplash.com/photo-1522199755839-a2bacb67c546?q=80&w=700&h=900&auto=format&fit=crop')" class="group relative flex-1 min-w-0 p-0 border-0 cursor-pointer rounded-xl overflow-hidden bg-[image:var(--img)] bg-cover bg-center brightness-[0.72] saturate-[0.95] transition-[flex-grow,filter] duration-500 ease-[cubic-bezier(0.2,0.7,0.2,1)] hover:grow-[4] hover:brightness-100 hover:saturate-[1.05] focus:grow-[4] focus:brightness-100 focus-visible:outline-3 focus-visible:outline-tgl12-acc focus-visible:-outline-offset-[3px] motion-reduce:transition-none">
<span aria-hidden="true" class="absolute inset-0 bg-[linear-gradient(0deg,rgba(10,6,4,0.7),transparent_55%)]"></span>
<span class="absolute right-3 top-4 z-[2] text-white text-[15px] font-bold tracking-[0.06em] [writing-mode:vertical-rl] rotate-180 [text-shadow:0_1px_4px_rgba(0,0,0,0.7)] transition-all duration-300 group-hover:[writing-mode:horizontal-tb] group-hover:rotate-0 group-hover:inset-x-0 group-hover:top-auto group-hover:bottom-4 group-hover:text-lg group-focus:[writing-mode:horizontal-tb] group-focus:rotate-0 group-focus:inset-x-0 group-focus:top-auto group-focus:bottom-4 group-focus:text-lg">Forests</span>
</button>
<button type="button" style="--img:url('https://images.unsplash.com/photo-1615663245857-ac93bb7c39e7?q=80&w=700&h=900&auto=format&fit=crop')" class="group relative flex-1 min-w-0 p-0 border-0 cursor-pointer rounded-xl overflow-hidden bg-[image:var(--img)] bg-cover bg-center brightness-[0.72] saturate-[0.95] transition-[flex-grow,filter] duration-500 ease-[cubic-bezier(0.2,0.7,0.2,1)] hover:grow-[4] hover:brightness-100 hover:saturate-[1.05] focus:grow-[4] focus:brightness-100 focus-visible:outline-3 focus-visible:outline-tgl12-acc focus-visible:-outline-offset-[3px] motion-reduce:transition-none">
<span aria-hidden="true" class="absolute inset-0 bg-[linear-gradient(0deg,rgba(10,6,4,0.7),transparent_55%)]"></span>
<span class="absolute right-3 top-4 z-[2] text-white text-[15px] font-bold tracking-[0.06em] [writing-mode:vertical-rl] rotate-180 [text-shadow:0_1px_4px_rgba(0,0,0,0.7)] transition-all duration-300 group-hover:[writing-mode:horizontal-tb] group-hover:rotate-0 group-hover:inset-x-0 group-hover:top-auto group-hover:bottom-4 group-hover:text-lg group-focus:[writing-mode:horizontal-tb] group-focus:rotate-0 group-focus:inset-x-0 group-focus:top-auto group-focus:bottom-4 group-focus:text-lg">Coast</span>
</button>
<button type="button" style="--img:url('https://images.unsplash.com/photo-1516035069371-29a1b244cc32?q=80&w=700&h=900&auto=format&fit=crop')" class="group relative flex-1 min-w-0 p-0 border-0 cursor-pointer rounded-xl overflow-hidden bg-[image:var(--img)] bg-cover bg-center brightness-[0.72] saturate-[0.95] transition-[flex-grow,filter] duration-500 ease-[cubic-bezier(0.2,0.7,0.2,1)] hover:grow-[4] hover:brightness-100 hover:saturate-[1.05] focus:grow-[4] focus:brightness-100 focus-visible:outline-3 focus-visible:outline-tgl12-acc focus-visible:-outline-offset-[3px] motion-reduce:transition-none">
<span aria-hidden="true" class="absolute inset-0 bg-[linear-gradient(0deg,rgba(10,6,4,0.7),transparent_55%)]"></span>
<span class="absolute right-3 top-4 z-[2] text-white text-[15px] font-bold tracking-[0.06em] [writing-mode:vertical-rl] rotate-180 [text-shadow:0_1px_4px_rgba(0,0,0,0.7)] transition-all duration-300 group-hover:[writing-mode:horizontal-tb] group-hover:rotate-0 group-hover:inset-x-0 group-hover:top-auto group-hover:bottom-4 group-hover:text-lg group-focus:[writing-mode:horizontal-tb] group-focus:rotate-0 group-focus:inset-x-0 group-focus:top-auto group-focus:bottom-4 group-focus:text-lg">Desert</span>
</button>
<button type="button" style="--img:url('https://images.unsplash.com/photo-1535632066927-ab7c9ab60908?q=80&w=700&h=900&auto=format&fit=crop')" class="group relative flex-1 min-w-0 p-0 border-0 cursor-pointer rounded-xl overflow-hidden bg-[image:var(--img)] bg-cover bg-center brightness-[0.72] saturate-[0.95] transition-[flex-grow,filter] duration-500 ease-[cubic-bezier(0.2,0.7,0.2,1)] hover:grow-[4] hover:brightness-100 hover:saturate-[1.05] focus:grow-[4] focus:brightness-100 focus-visible:outline-3 focus-visible:outline-tgl12-acc focus-visible:-outline-offset-[3px] motion-reduce:transition-none">
<span aria-hidden="true" class="absolute inset-0 bg-[linear-gradient(0deg,rgba(10,6,4,0.7),transparent_55%)]"></span>
<span class="absolute right-3 top-4 z-[2] text-white text-[15px] font-bold tracking-[0.06em] [writing-mode:vertical-rl] rotate-180 [text-shadow:0_1px_4px_rgba(0,0,0,0.7)] transition-all duration-300 group-hover:[writing-mode:horizontal-tb] group-hover:rotate-0 group-hover:inset-x-0 group-hover:top-auto group-hover:bottom-4 group-hover:text-lg group-focus:[writing-mode:horizontal-tb] group-focus:rotate-0 group-focus:inset-x-0 group-focus:top-auto group-focus:bottom-4 group-focus:text-lg">Cities</span>
</button>
</div>
</section>@import "tailwindcss";
@theme {
--color-tgl12-bg: #14110f;
--color-tgl12-bg: oklch(0.17 0.008 50);
--color-tgl12-acc: #e2683f;
--color-tgl12-acc: oklch(0.66 0.17 35);
--font-tgl12-sans: 'Space Grotesk', system-ui, sans-serif;
}
.tgl-12 {
width: 100%;
min-height: 100svh;
}
.tgl-12 ::selection {
background: var(--color-tgl12-acc);
color: #fff;
}@import "tailwindcss";
@theme {
--color-tgl12-bg: #14110f;
--color-tgl12-bg: oklch(0.17 0.008 50);
--color-tgl12-acc: #e2683f;
--color-tgl12-acc: oklch(0.66 0.17 35);
--font-tgl12-sans: 'Space Grotesk', system-ui, sans-serif;
}
.tgl-12 {
width: 100%;
min-height: 100svh;
}
.tgl-12 ::selection {
background: var(--color-tgl12-acc);
color: #fff;
}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-tgl12-bg: #14110f;
--color-tgl12-bg: oklch(0.17 0.008 50);
--color-tgl12-acc: #e2683f;
--color-tgl12-acc: oklch(0.66 0.17 35);
--font-tgl12-sans: 'Space Grotesk', system-ui, sans-serif;
}
.tgl-12 {
width: 100%;
min-height: 100svh;
}
.tgl-12 ::selection {
background: var(--color-tgl12-acc);
color: #fff;
}@import "tailwindcss";
@theme {
--color-tgl12-bg: #14110f;
--color-tgl12-bg: oklch(0.17 0.008 50);
--color-tgl12-acc: #e2683f;
--color-tgl12-acc: oklch(0.66 0.17 35);
--font-tgl12-sans: 'Space Grotesk', system-ui, sans-serif;
}
.tgl-12 {
width: 100%;
min-height: 100svh;
}
.tgl-12 ::selection {
background: var(--color-tgl12-acc);
color: #fff;
}<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:grow-[4]andfocus:grow-[4]landing side by side is the port's whole argument on this pattern: in CSS the two were a comma-joined selector, and the focus half is exactly what gets dropped.writing-modehas no utility and should not: it is a typographic mode with two values anyone would ever use here, and the arbitrary form reads fine.- UI change from the CSS original: the collapsed label is now visible at rest rather than only appearing on hover, so a touch user can read all five categories before tapping anything.
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 Accordion Image Gallery with Flex-Grow on Hover & Focus
Source: https://codefronts.com/snippets/tailwind-css-image-gallery/tailwind-accordion-image-gallery-flex-grow/
A compact row of vertical image strips that expand on hover or keyboard focus while their neighbours shrink. Every panel is a real <button>, so the accordion opens on focus exactly as it does on hover — the port states both on the same element, one class apart.
## HTML
```html
<section class="tgl-12 w-full min-h-svh grid place-items-center bg-tgl12-bg font-tgl12-sans px-5 py-10" aria-label="Accordion image gallery">
<div class="flex gap-2 w-[min(880px,100%)] h-[min(440px,60vh)]">
<button type="button" style="--img:url('https://images.unsplash.com/photo-1531297484001-80022131f5a1?q=80&w=700&h=900&auto=format&fit=crop')" class="group relative flex-1 min-w-0 p-0 border-0 cursor-pointer rounded-xl overflow-hidden bg-[image:var(--img)] bg-cover bg-center brightness-[0.72] saturate-[0.95] transition-[flex-grow,filter] duration-500 ease-[cubic-bezier(0.2,0.7,0.2,1)] hover:grow-[4] hover:brightness-100 hover:saturate-[1.05] focus:grow-[4] focus:brightness-100 focus-visible:outline-3 focus-visible:outline-tgl12-acc focus-visible:-outline-offset-[3px] motion-reduce:transition-none">
<span aria-hidden="true" class="absolute inset-0 bg-[linear-gradient(0deg,rgba(10,6,4,0.7),transparent_55%)]"></span>
<span class="absolute right-3 top-4 z-[2] text-white text-[15px] font-bold tracking-[0.06em] [writing-mode:vertical-rl] rotate-180 [text-shadow:0_1px_4px_rgba(0,0,0,0.7)] transition-all duration-300 group-hover:[writing-mode:horizontal-tb] group-hover:rotate-0 group-hover:inset-x-0 group-hover:top-auto group-hover:bottom-4 group-hover:text-lg group-focus:[writing-mode:horizontal-tb] group-focus:rotate-0 group-focus:inset-x-0 group-focus:top-auto group-focus:bottom-4 group-focus:text-lg">Peaks</span>
</button>
<button type="button" style="--img:url('https://images.unsplash.com/photo-1522199755839-a2bacb67c546?q=80&w=700&h=900&auto=format&fit=crop')" class="group relative flex-1 min-w-0 p-0 border-0 cursor-pointer rounded-xl overflow-hidden bg-[image:var(--img)] bg-cover bg-center brightness-[0.72] saturate-[0.95] transition-[flex-grow,filter] duration-500 ease-[cubic-bezier(0.2,0.7,0.2,1)] hover:grow-[4] hover:brightness-100 hover:saturate-[1.05] focus:grow-[4] focus:brightness-100 focus-visible:outline-3 focus-visible:outline-tgl12-acc focus-visible:-outline-offset-[3px] motion-reduce:transition-none">
<span aria-hidden="true" class="absolute inset-0 bg-[linear-gradient(0deg,rgba(10,6,4,0.7),transparent_55%)]"></span>
<span class="absolute right-3 top-4 z-[2] text-white text-[15px] font-bold tracking-[0.06em] [writing-mode:vertical-rl] rotate-180 [text-shadow:0_1px_4px_rgba(0,0,0,0.7)] transition-all duration-300 group-hover:[writing-mode:horizontal-tb] group-hover:rotate-0 group-hover:inset-x-0 group-hover:top-auto group-hover:bottom-4 group-hover:text-lg group-focus:[writing-mode:horizontal-tb] group-focus:rotate-0 group-focus:inset-x-0 group-focus:top-auto group-focus:bottom-4 group-focus:text-lg">Forests</span>
</button>
<button type="button" style="--img:url('https://images.unsplash.com/photo-1615663245857-ac93bb7c39e7?q=80&w=700&h=900&auto=format&fit=crop')" class="group relative flex-1 min-w-0 p-0 border-0 cursor-pointer rounded-xl overflow-hidden bg-[image:var(--img)] bg-cover bg-center brightness-[0.72] saturate-[0.95] transition-[flex-grow,filter] duration-500 ease-[cubic-bezier(0.2,0.7,0.2,1)] hover:grow-[4] hover:brightness-100 hover:saturate-[1.05] focus:grow-[4] focus:brightness-100 focus-visible:outline-3 focus-visible:outline-tgl12-acc focus-visible:-outline-offset-[3px] motion-reduce:transition-none">
<span aria-hidden="true" class="absolute inset-0 bg-[linear-gradient(0deg,rgba(10,6,4,0.7),transparent_55%)]"></span>
<span class="absolute right-3 top-4 z-[2] text-white text-[15px] font-bold tracking-[0.06em] [writing-mode:vertical-rl] rotate-180 [text-shadow:0_1px_4px_rgba(0,0,0,0.7)] transition-all duration-300 group-hover:[writing-mode:horizontal-tb] group-hover:rotate-0 group-hover:inset-x-0 group-hover:top-auto group-hover:bottom-4 group-hover:text-lg group-focus:[writing-mode:horizontal-tb] group-focus:rotate-0 group-focus:inset-x-0 group-focus:top-auto group-focus:bottom-4 group-focus:text-lg">Coast</span>
</button>
<button type="button" style="--img:url('https://images.unsplash.com/photo-1516035069371-29a1b244cc32?q=80&w=700&h=900&auto=format&fit=crop')" class="group relative flex-1 min-w-0 p-0 border-0 cursor-pointer rounded-xl overflow-hidden bg-[image:var(--img)] bg-cover bg-center brightness-[0.72] saturate-[0.95] transition-[flex-grow,filter] duration-500 ease-[cubic-bezier(0.2,0.7,0.2,1)] hover:grow-[4] hover:brightness-100 hover:saturate-[1.05] focus:grow-[4] focus:brightness-100 focus-visible:outline-3 focus-visible:outline-tgl12-acc focus-visible:-outline-offset-[3px] motion-reduce:transition-none">
<span aria-hidden="true" class="absolute inset-0 bg-[linear-gradient(0deg,rgba(10,6,4,0.7),transparent_55%)]"></span>
<span class="absolute right-3 top-4 z-[2] text-white text-[15px] font-bold tracking-[0.06em] [writing-mode:vertical-rl] rotate-180 [text-shadow:0_1px_4px_rgba(0,0,0,0.7)] transition-all duration-300 group-hover:[writing-mode:horizontal-tb] group-hover:rotate-0 group-hover:inset-x-0 group-hover:top-auto group-hover:bottom-4 group-hover:text-lg group-focus:[writing-mode:horizontal-tb] group-focus:rotate-0 group-focus:inset-x-0 group-focus:top-auto group-focus:bottom-4 group-focus:text-lg">Desert</span>
</button>
<button type="button" style="--img:url('https://images.unsplash.com/photo-1535632066927-ab7c9ab60908?q=80&w=700&h=900&auto=format&fit=crop')" class="group relative flex-1 min-w-0 p-0 border-0 cursor-pointer rounded-xl overflow-hidden bg-[image:var(--img)] bg-cover bg-center brightness-[0.72] saturate-[0.95] transition-[flex-grow,filter] duration-500 ease-[cubic-bezier(0.2,0.7,0.2,1)] hover:grow-[4] hover:brightness-100 hover:saturate-[1.05] focus:grow-[4] focus:brightness-100 focus-visible:outline-3 focus-visible:outline-tgl12-acc focus-visible:-outline-offset-[3px] motion-reduce:transition-none">
<span aria-hidden="true" class="absolute inset-0 bg-[linear-gradient(0deg,rgba(10,6,4,0.7),transparent_55%)]"></span>
<span class="absolute right-3 top-4 z-[2] text-white text-[15px] font-bold tracking-[0.06em] [writing-mode:vertical-rl] rotate-180 [text-shadow:0_1px_4px_rgba(0,0,0,0.7)] transition-all duration-300 group-hover:[writing-mode:horizontal-tb] group-hover:rotate-0 group-hover:inset-x-0 group-hover:top-auto group-hover:bottom-4 group-hover:text-lg group-focus:[writing-mode:horizontal-tb] group-focus:rotate-0 group-focus:inset-x-0 group-focus:top-auto group-focus:bottom-4 group-focus:text-lg">Cities</span>
</button>
</div>
</section>
```
## CSS
```css
@import "tailwindcss";
@theme {
--color-tgl12-bg: #14110f;
--color-tgl12-bg: oklch(0.17 0.008 50);
--color-tgl12-acc: #e2683f;
--color-tgl12-acc: oklch(0.66 0.17 35);
--font-tgl12-sans: 'Space Grotesk', system-ui, sans-serif;
}
.tgl-12 {
width: 100%;
min-height: 100svh;
}
.tgl-12 ::selection {
background: var(--color-tgl12-acc);
color: #fff;
}
```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 Accordion Image Gallery with Flex-Grow on Hover & Focus
Source: https://codefronts.com/snippets/tailwind-css-image-gallery/tailwind-accordion-image-gallery-flex-grow/
A compact row of vertical image strips that expand on hover or keyboard focus while their neighbours shrink. Every panel is a real <button>, so the accordion opens on focus exactly as it does on hover — the port states both on the same element, one class apart.
## HTML
```html
<section class="tgl-12 w-full min-h-svh grid place-items-center bg-tgl12-bg font-tgl12-sans px-5 py-10" aria-label="Accordion image gallery">
<div class="flex gap-2 w-[min(880px,100%)] h-[min(440px,60vh)]">
<button type="button" style="--img:url('https://images.unsplash.com/photo-1531297484001-80022131f5a1?q=80&w=700&h=900&auto=format&fit=crop')" class="group relative flex-1 min-w-0 p-0 border-0 cursor-pointer rounded-xl overflow-hidden bg-[image:var(--img)] bg-cover bg-center brightness-[0.72] saturate-[0.95] transition-[flex-grow,filter] duration-500 ease-[cubic-bezier(0.2,0.7,0.2,1)] hover:grow-[4] hover:brightness-100 hover:saturate-[1.05] focus:grow-[4] focus:brightness-100 focus-visible:outline-3 focus-visible:outline-tgl12-acc focus-visible:-outline-offset-[3px] motion-reduce:transition-none">
<span aria-hidden="true" class="absolute inset-0 bg-[linear-gradient(0deg,rgba(10,6,4,0.7),transparent_55%)]"></span>
<span class="absolute right-3 top-4 z-[2] text-white text-[15px] font-bold tracking-[0.06em] [writing-mode:vertical-rl] rotate-180 [text-shadow:0_1px_4px_rgba(0,0,0,0.7)] transition-all duration-300 group-hover:[writing-mode:horizontal-tb] group-hover:rotate-0 group-hover:inset-x-0 group-hover:top-auto group-hover:bottom-4 group-hover:text-lg group-focus:[writing-mode:horizontal-tb] group-focus:rotate-0 group-focus:inset-x-0 group-focus:top-auto group-focus:bottom-4 group-focus:text-lg">Peaks</span>
</button>
<button type="button" style="--img:url('https://images.unsplash.com/photo-1522199755839-a2bacb67c546?q=80&w=700&h=900&auto=format&fit=crop')" class="group relative flex-1 min-w-0 p-0 border-0 cursor-pointer rounded-xl overflow-hidden bg-[image:var(--img)] bg-cover bg-center brightness-[0.72] saturate-[0.95] transition-[flex-grow,filter] duration-500 ease-[cubic-bezier(0.2,0.7,0.2,1)] hover:grow-[4] hover:brightness-100 hover:saturate-[1.05] focus:grow-[4] focus:brightness-100 focus-visible:outline-3 focus-visible:outline-tgl12-acc focus-visible:-outline-offset-[3px] motion-reduce:transition-none">
<span aria-hidden="true" class="absolute inset-0 bg-[linear-gradient(0deg,rgba(10,6,4,0.7),transparent_55%)]"></span>
<span class="absolute right-3 top-4 z-[2] text-white text-[15px] font-bold tracking-[0.06em] [writing-mode:vertical-rl] rotate-180 [text-shadow:0_1px_4px_rgba(0,0,0,0.7)] transition-all duration-300 group-hover:[writing-mode:horizontal-tb] group-hover:rotate-0 group-hover:inset-x-0 group-hover:top-auto group-hover:bottom-4 group-hover:text-lg group-focus:[writing-mode:horizontal-tb] group-focus:rotate-0 group-focus:inset-x-0 group-focus:top-auto group-focus:bottom-4 group-focus:text-lg">Forests</span>
</button>
<button type="button" style="--img:url('https://images.unsplash.com/photo-1615663245857-ac93bb7c39e7?q=80&w=700&h=900&auto=format&fit=crop')" class="group relative flex-1 min-w-0 p-0 border-0 cursor-pointer rounded-xl overflow-hidden bg-[image:var(--img)] bg-cover bg-center brightness-[0.72] saturate-[0.95] transition-[flex-grow,filter] duration-500 ease-[cubic-bezier(0.2,0.7,0.2,1)] hover:grow-[4] hover:brightness-100 hover:saturate-[1.05] focus:grow-[4] focus:brightness-100 focus-visible:outline-3 focus-visible:outline-tgl12-acc focus-visible:-outline-offset-[3px] motion-reduce:transition-none">
<span aria-hidden="true" class="absolute inset-0 bg-[linear-gradient(0deg,rgba(10,6,4,0.7),transparent_55%)]"></span>
<span class="absolute right-3 top-4 z-[2] text-white text-[15px] font-bold tracking-[0.06em] [writing-mode:vertical-rl] rotate-180 [text-shadow:0_1px_4px_rgba(0,0,0,0.7)] transition-all duration-300 group-hover:[writing-mode:horizontal-tb] group-hover:rotate-0 group-hover:inset-x-0 group-hover:top-auto group-hover:bottom-4 group-hover:text-lg group-focus:[writing-mode:horizontal-tb] group-focus:rotate-0 group-focus:inset-x-0 group-focus:top-auto group-focus:bottom-4 group-focus:text-lg">Coast</span>
</button>
<button type="button" style="--img:url('https://images.unsplash.com/photo-1516035069371-29a1b244cc32?q=80&w=700&h=900&auto=format&fit=crop')" class="group relative flex-1 min-w-0 p-0 border-0 cursor-pointer rounded-xl overflow-hidden bg-[image:var(--img)] bg-cover bg-center brightness-[0.72] saturate-[0.95] transition-[flex-grow,filter] duration-500 ease-[cubic-bezier(0.2,0.7,0.2,1)] hover:grow-[4] hover:brightness-100 hover:saturate-[1.05] focus:grow-[4] focus:brightness-100 focus-visible:outline-3 focus-visible:outline-tgl12-acc focus-visible:-outline-offset-[3px] motion-reduce:transition-none">
<span aria-hidden="true" class="absolute inset-0 bg-[linear-gradient(0deg,rgba(10,6,4,0.7),transparent_55%)]"></span>
<span class="absolute right-3 top-4 z-[2] text-white text-[15px] font-bold tracking-[0.06em] [writing-mode:vertical-rl] rotate-180 [text-shadow:0_1px_4px_rgba(0,0,0,0.7)] transition-all duration-300 group-hover:[writing-mode:horizontal-tb] group-hover:rotate-0 group-hover:inset-x-0 group-hover:top-auto group-hover:bottom-4 group-hover:text-lg group-focus:[writing-mode:horizontal-tb] group-focus:rotate-0 group-focus:inset-x-0 group-focus:top-auto group-focus:bottom-4 group-focus:text-lg">Desert</span>
</button>
<button type="button" style="--img:url('https://images.unsplash.com/photo-1535632066927-ab7c9ab60908?q=80&w=700&h=900&auto=format&fit=crop')" class="group relative flex-1 min-w-0 p-0 border-0 cursor-pointer rounded-xl overflow-hidden bg-[image:var(--img)] bg-cover bg-center brightness-[0.72] saturate-[0.95] transition-[flex-grow,filter] duration-500 ease-[cubic-bezier(0.2,0.7,0.2,1)] hover:grow-[4] hover:brightness-100 hover:saturate-[1.05] focus:grow-[4] focus:brightness-100 focus-visible:outline-3 focus-visible:outline-tgl12-acc focus-visible:-outline-offset-[3px] motion-reduce:transition-none">
<span aria-hidden="true" class="absolute inset-0 bg-[linear-gradient(0deg,rgba(10,6,4,0.7),transparent_55%)]"></span>
<span class="absolute right-3 top-4 z-[2] text-white text-[15px] font-bold tracking-[0.06em] [writing-mode:vertical-rl] rotate-180 [text-shadow:0_1px_4px_rgba(0,0,0,0.7)] transition-all duration-300 group-hover:[writing-mode:horizontal-tb] group-hover:rotate-0 group-hover:inset-x-0 group-hover:top-auto group-hover:bottom-4 group-hover:text-lg group-focus:[writing-mode:horizontal-tb] group-focus:rotate-0 group-focus:inset-x-0 group-focus:top-auto group-focus:bottom-4 group-focus:text-lg">Cities</span>
</button>
</div>
</section>
```
## CSS
```css
@import "tailwindcss";
@theme {
--color-tgl12-bg: #14110f;
--color-tgl12-bg: oklch(0.17 0.008 50);
--color-tgl12-acc: #e2683f;
--color-tgl12-acc: oklch(0.66 0.17 35);
--font-tgl12-sans: 'Space Grotesk', system-ui, sans-serif;
}
.tgl-12 {
width: 100%;
min-height: 100svh;
}
.tgl-12 ::selection {
background: var(--color-tgl12-acc);
color: #fff;
}
```How this works
The control is a button, and that is the accessibility story. Five <button> elements share the row at flex-1; the interacted one takes grow-[4] on both hover: and focus:. Because the element is natively focusable, tabbing through the row opens each panel in turn with no extra markup.
The label rotates rather than fades. Vertical at rest so a collapsed 60px strip is still legible, horizontal and larger once open — two writing-mode arbitrary properties driven by the panel's group.
This animation touches layout on purpose. flex-grow is the technique; five panels and a 500ms curve keep it smooth, and the honest note is that fifteen would not be.
Make it yours
- Open width:
hover:grow-[4]— 2 is subtle, 6 is dramatic. - Vertical accordion:
flex-colon the row, and the same grow utilities expand height instead. - Swap background images for inner
<img>elements when each panel needs its own alt text.
Gotchas — read before shipping
- Use
focus:here, notfocus-visible:— the panel should open for any focus, including a click that lands focus on the button. - Background images have no alt, so every button needs real text or an
aria-label. The visible label does that job here. min-w-0is mandatory on flex children that must shrink; without it the row overflows instead of compressing.
Browser support
| Chrome | Safari | Firefox | Edge |
|---|---|---|---|
| 111+ | 16.4+ | 128+ | 111+ |
Flexbox grow transitions and writing-mode are universal; the floor is Tailwind v4's generated sheet.