Grid that adapts layout based on container size and content using Container Queries and :has() selector.
Browser Support
Combines @container queries for responsive sizing with :has(img) to change layout based on content.
Preview
Cards adapt layout based on container width and content.
Wide container
Card with Image
This card has an image, so it expands on wider containers.
Text Only Card
This card has no image, so the layout is compact.
Narrow container
With Image
Image adapts to narrow space.
Card with Image
This card has an image, so it expands to show the image alongside the content on wider containers.
Text Only Card
This card has no image, so the layout is compact and vertical.
Another Text Card
Content adjusts automatically based on what's inside the card.
Another Image Card
The grid responds to both container size and card content.
Narrow Card
In a narrow container, cards stack vertically.
With Image
Image cards also adapt to narrow space.
Installation
Usage
import { AdaptiveGrid, AdaptiveCard } from "@/components/ui/adaptive-grid"
<AdaptiveGrid>
<AdaptiveCard title="Card with image" image="/image.jpg">
Description text
</AdaptiveCard>
<AdaptiveCard title="Card without image">
This card has no image, so layout adjusts automatically.
</AdaptiveCard>
</AdaptiveGrid>CSS Feature
The component uses Tailwind's Container Queries plugin with the :has() selector:
// AdaptiveCard uses :has() to detect if it contains an image
className={cn(
"@container group/card",
// Layout changes based on content with :has()
"has-[img]:grid has-[img]:@sm:grid-cols-[140px_1fr]",
"[&:not(:has(img))]:flex [&:not(:has(img))]:flex-col",
)}
// AdaptiveGrid uses container queries for responsive columns
className={cn(
"@container",
"grid-cols-1 @sm:grid-cols-2 @lg:grid-cols-3 @2xl:grid-cols-4",
)}Props
| Prop | Type | Default | Description |
|---|---|---|---|
| image | string | - | Optional image URL |
| title | string | - | Card title |
| minCardWidth | number | 280 | Minimum card width (AdaptiveGrid) |
| className | string | - | Additional CSS classes |