Photo Grid Gallery
An even, responsive grid of captioned photos with no JavaScript.
6 frameworksBeginner
A tight three-across square grid with a like and comment overlay on interaction.
<!--
The tight 3-across square grid of a social profile. The like/comment overlay
reveals on group-hover AND group-focus-visible, so it is reachable by keyboard,
and motion-reduce drops the fade. grid-cols-3 holds at 320px (three ~100px
squares); no lg bump - the three-column identity is the point.
-->
<ul class="grid w-full list-none grid-cols-3 gap-1 p-0 sm:gap-2">
<li>
<button type="button" class="group relative block w-full overflow-hidden focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-blue-600 focus-visible:ring-offset-2 dark:focus-visible:ring-blue-400 dark:focus-visible:ring-offset-gray-950">
<span class="block aspect-square w-full bg-gradient-to-br from-sky-400 to-indigo-600" role="img" aria-label="Sky-blue to indigo gradient"></span>
<span class="absolute inset-0 flex items-center justify-center gap-4 bg-black/45 text-sm font-semibold text-white opacity-0 transition-opacity group-hover:opacity-100 group-focus-visible:opacity-100 motion-reduce:transition-none" aria-hidden="true">
<span>♥ 128</span><span>💬 12</span>
</span>
<span class="sr-only">Coastline: 128 likes, 12 comments</span>
</button>
</li>
<li>
<button type="button" class="group relative block w-full overflow-hidden focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-blue-600 focus-visible:ring-offset-2 dark:focus-visible:ring-blue-400 dark:focus-visible:ring-offset-gray-950">
<span class="block aspect-square w-full bg-gradient-to-br from-rose-400 to-orange-500" role="img" aria-label="Rose to orange gradient"></span>
<span class="absolute inset-0 flex items-center justify-center gap-4 bg-black/45 text-sm font-semibold text-white opacity-0 transition-opacity group-hover:opacity-100 group-focus-visible:opacity-100 motion-reduce:transition-none" aria-hidden="true">
<span>♥ 96</span><span>💬 5</span>
</span>
<span class="sr-only">Canyon: 96 likes, 5 comments</span>
</button>
</li>
<li>
<button type="button" class="group relative block w-full overflow-hidden focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-blue-600 focus-visible:ring-offset-2 dark:focus-visible:ring-blue-400 dark:focus-visible:ring-offset-gray-950">
<span class="block aspect-square w-full bg-gradient-to-br from-emerald-400 to-teal-600" role="img" aria-label="Emerald to teal gradient"></span>
<span class="absolute inset-0 flex items-center justify-center gap-4 bg-black/45 text-sm font-semibold text-white opacity-0 transition-opacity group-hover:opacity-100 group-focus-visible:opacity-100 motion-reduce:transition-none" aria-hidden="true">
<span>♥ 204</span><span>💬 31</span>
</span>
<span class="sr-only">Forest: 204 likes, 31 comments</span>
</button>
</li>
</ul>| Prop | Type | Default | Description |
|---|---|---|---|
itemsrequired | SocialTile[] | - | The array of items to render. |
className | string | - | Additional classes merged onto the root element. |
The overlay reveals on `group-hover` and `group-focus-visible` so it is reachable by keyboard, with the counts also mirrored in an `sr-only` label since the overlay is decorative. `grid-cols-3` holds even at 320px, and there is no `lg` bump on purpose - the three-column identity is the point.