skills/css-container-queries/SKILL.md
Apply CSS container queries for component-based responsive design. Use when implementing responsive components that adapt to their container size rather than viewport size.
npx skillsauth add Chris-Maskey/opencode-config css-container-queriesInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
A guide for implementing container-based responsive design using CSS container queries and Tailwind CSS.
Container queries enable styling elements based on their container's size rather than the viewport size. Unlike media queries that respond to the browser window, container queries make components self-contained and truly reusable.
Key Concept:
/* Define a container */
.card-wrapper {
container-type: inline-size;
container-name: card;
}
/* Query the container */
@container card (min-width: 400px) {
.card-title {
font-size: 2rem;
}
}
Tailwind Approach:
<!-- Define a container -->
<div class="@container">
<!-- Query the container -->
<div class="@lg:grid-cols-2">
<!-- Content adapts to container, not viewport -->
</div>
</div>
| Feature | Media Query | Container Query |
|---------|-------------|-----------------|
| Responds to | Viewport size | Container size |
| Reusability | Layout-dependent | Fully portable |
| Use case | Page layouts | Component styling |
| Syntax | @media | @container |
1. Component Portability
2. Simpler Component Logic
3. Better for Design Systems
4. Modern Web Architecture
🤔 Use Container Queries when:
🤔 Use Media Queries when:
Review and refactor responsive components to use container queries where appropriate.
Step 1: Define the container
.component-wrapper {
container-type: inline-size; /* or 'size' for both dimensions */
container-name: myComponent; /* optional but recommended */
}
Step 2: Add container queries
/* Use the container name */
@container myComponent (min-width: 400px) {
.component-title {
font-size: 2rem;
}
}
/* Or query nearest container */
@container (min-width: 400px) {
.component-title {
font-size: 2rem;
}
}
Step 3: Use modern range syntax (optional)
@container (400px <= width <= 800px) {
.component-content {
display: grid;
grid-template-columns: repeat(2, 1fr);
}
}
Step 1: Define container with @container class
<div class="@container">
<!-- This is now a container context -->
</div>
Step 2: Use container query variants
<div class="@container">
<div class="grid @lg:grid-cols-2 @xl:grid-cols-3">
<!-- Responds to container size, not viewport -->
</div>
</div>
Available Tailwind Container Breakpoints:
@3xs - @container (width >= 16rem) (256px)@2xs - @container (width >= 18rem) (288px)@xs - @container (width >= 20rem) (320px)@sm - @container (width >= 24rem) (384px)@md - @container (width >= 28rem) (448px)@lg - @container (width >= 32rem) (512px)@xl - @container (width >= 36rem) (576px)@2xl - @container (width >= 42rem) (672px)@3xl - @container (width >= 48rem) (768px)@4xl - @container (width >= 56rem) (896px)@5xl - @container (width >= 64rem) (1024px)@6xl - @container (width >= 72rem) (1152px)@7xl - @container (width >= 80rem) (1280px)📝 Note: These are Tailwind's default breakpoints. You can customize them in globals.css (Tailwind v4) using CSS variables or use arbitrary values like @min-[500px]:grid for custom container widths.
Step 3: Named containers (Tailwind)
<!-- Define named container -->
<div class="@container/main">
<!-- Query specific container -->
<div class="@lg/main:grid-cols-3">
<!-- Content -->
</div>
</div>
Pattern 1: Card Component
<!-- Tailwind -->
<div class="@container">
<article class="@lg:flex @lg:gap-4">
<img class="@lg:w-48" src="..." alt="..." />
<div class="@lg:flex-1">
<h2 class="text-xl @lg:text-2xl">Title</h2>
<p class="@lg:text-base">Description</p>
</div>
</article>
</div>
Pattern 2: Responsive Grid
<!-- Tailwind -->
<div class="@container">
<div class="grid @sm:grid-cols-2 @lg:grid-cols-3 @2xl:grid-cols-4 gap-4">
<!-- Items adapt to container width -->
</div>
</div>
Pattern 3: Mixed Container + Media Queries
<!-- Use media queries for layout, container queries for components -->
<main class="max-w-7xl mx-auto md:grid md:grid-cols-3">
<!-- Sidebar: narrow container -->
<aside class="md:col-span-1">
<div class="@container">
<div class="@lg:hidden">Compact view</div>
</div>
</aside>
<!-- Main: wide container -->
<div class="md:col-span-2">
<div class="@container">
<div class="@2xl:grid-cols-3">Full width view</div>
</div>
</div>
</main>
✅ Focus on:
⚠️ Watch out for:
❌ Avoid:
After implementing container queries:
✅ Supported:
💡 Tip: For older browsers, use @supports or progressive enhancement:
/* Fallback for older browsers */
.component {
padding: 1rem;
}
/* Enhanced with container queries */
@supports (container-type: inline-size) {
@container (min-width: 400px) {
.component {
padding: 2rem;
}
}
}
<!-- Tailwind: Reusable card adapts to any container -->
<div class="@container">
<article class="p-4 @md:p-6 @lg:flex @lg:gap-6">
<img class="w-full @lg:w-64 rounded" src="card.jpg" alt="" />
<div>
<h2 class="text-lg @md:text-xl @lg:text-2xl font-bold">
Card Title
</h2>
<p class="text-sm @md:text-base @lg:text-lg">
Card description that adapts to container width.
</p>
<button class="mt-4 @md:mt-6">Action</button>
</div>
</article>
</div>
Why it's good: Card is self-contained and works in any layout context.
<!-- Tailwind: Component depends on viewport, not container -->
<article class="p-4 md:p-6 lg:flex lg:gap-6">
<img class="w-full lg:w-64 rounded" src="card.jpg" alt="" />
<div>
<h2 class="text-lg md:text-xl lg:text-2xl font-bold">
Card Title
</h2>
</div>
</article>
Why it's bad: Card assumes it's always full width at md breakpoint. Breaks when placed in a sidebar.
<!-- Tailwind: Multiple containers with clear names -->
<div class="@container/sidebar">
<nav class="@lg/sidebar:grid-cols-1">
<!-- Sidebar navigation -->
</nav>
</div>
<div class="@container/main">
<div class="@lg/main:grid-cols-3">
<!-- Main content grid -->
</div>
</div>
Why it's good: Clear which container each query refers to.
❌ Mistake 1: Using container queries for page layouts
<!-- Don't do this -->
<body class="@container">
<main class="@lg:grid @lg:grid-cols-3">
Fix: Use media queries for page-level layouts.
❌ Mistake 2: Forgetting to define the container
<!-- Don't do this -->
<div>
<div class="@lg:grid-cols-2"><!-- Won't work! --></div>
</div>
Fix: Always add @container to the parent.
❌ Mistake 3: Fixed heights with responsive content
/* Don't do this */
.container {
height: 400px; /* Fixed height */
}
@container (min-width: 600px) {
.content {
columns: 2; /* Text will overflow! */
}
}
Fix: Use min-height or let content determine height.
❌ Mistake 4: Too many nested containers
<!-- Don't do this -->
<div class="@container">
<div class="@container">
<div class="@container">
<div class="@lg:..."><!-- Confusing! --></div>
</div>
</div>
</div>
Fix: Use named containers and keep nesting shallow.
/* Define container */
.wrapper {
container-type: inline-size; /* or 'size' */
container-name: myContainer; /* optional */
}
/* Query container */
@container myContainer (min-width: 400px) {
/* styles */
}
/* Modern range syntax */
@container (400px <= width <= 800px) {
/* styles */
}
<!-- Define container -->
<div class="@container">
<!-- Use container variants -->
<div class="@sm:text-lg @md:grid-cols-2">
</div>
<!-- Named container -->
<div class="@container/name">
<div class="@lg/name:grid-cols-3">
</div>
tools
Anti-patterns and mistakes to avoid as a product manager. Use when evaluating leadership behaviors, improving team dynamics, reflecting on management practices, or onboarding new product managers.
development
Review UI code for Web Interface Guidelines compliance. Use when asked to "review my UI", "check accessibility", "audit design", "review UX", or "check my site against best practices".
testing
Design effective CTAs using visual attention and gaze psychology principles. Use when designing landing pages, button hierarchies, conversion elements, or optimizing user attention flow through interfaces.
tools
Run agent-browser + Chrome inside Vercel Sandbox microVMs for browser automation from any Vercel-deployed app. Use when the user needs browser automation in a Vercel app (Next.js, SvelteKit, Nuxt, Remix, Astro, etc.), wants to run headless Chrome without binary size limits, needs persistent browser sessions across commands, or wants ephemeral isolated browser environments. Triggers include "Vercel Sandbox browser", "microVM Chrome", "agent-browser in sandbox", "browser automation on Vercel", or any task requiring Chrome in a Vercel Sandbox.