flpbalada-css-container-queries
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseCSS Container Queries
CSS容器查询
A guide for implementing container-based responsive design using CSS container queries and Tailwind CSS.
一份关于使用CSS容器查询和Tailwind CSS实现基于容器的响应式设计的指南。
What
什么是容器查询
What are Container Queries?
什么是容器查询?
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:
css
/* 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:
html
<!-- Define a container -->
<div class="@container">
<!-- Query the container -->
<div class="@lg:grid-cols-2">
<!-- Content adapts to container, not viewport -->
</div>
</div>容器查询允许根据元素的容器尺寸而非视口尺寸为元素设置样式。与响应浏览器窗口的媒体查询不同,容器查询让组件具备独立性,实现真正的可复用性。
核心概念:
css
/* 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实现方式:
html
<!-- Define a container -->
<div class="@container">
<!-- Query the container -->
<div class="@lg:grid-cols-2">
<!-- Content adapts to container, not viewport -->
</div>
</div>Container Query vs Media Query
容器查询 vs 媒体查询
| Feature | Media Query | Container Query |
|---|---|---|
| Responds to | Viewport size | Container size |
| Reusability | Layout-dependent | Fully portable |
| Use case | Page layouts | Component styling |
| Syntax | | |
| 特性 | 媒体查询 | 容器查询 |
|---|---|---|
| 响应对象 | 视口尺寸 | 容器尺寸 |
| 可复用性 | 依赖布局 | 完全可移植 |
| 适用场景 | 页面布局 | 组件样式 |
| 语法 | | |
Why
为什么使用容器查询
💡 Why Use Container Queries?
💡 为什么使用容器查询?
1. Component Portability
- Components adapt to their context, not the viewport
- Same component works in sidebar (narrow) or main area (wide)
- No need for different component variants
2. Simpler Component Logic
- Components don't need to know about page layout
- Follows single responsibility principle
- Reduces coupling between components and layouts
3. Better for Design Systems
- Components are truly self-contained
- Works in any layout context (grid, flex, sidebar)
- Easier to maintain and test in isolation
4. Modern Web Architecture
- Aligns with component-based frameworks (React, Vue, Svelte)
- Better for micro-frontends
- More predictable behavior
1. 组件可移植性
- 组件根据所在环境自适应,而非视口
- 同一组件可在侧边栏(窄)或主区域(宽)正常工作
- 无需创建不同的组件变体
2. 更简洁的组件逻辑
- 组件无需了解页面布局细节
- 遵循单一职责原则
- 降低组件与布局之间的耦合度
3. 更适配设计系统
- 组件真正实现独立封装
- 可在任意布局环境(网格、弹性布局、侧边栏)中使用
- 更易于独立维护和测试
4. 适配现代Web架构
- 与基于组件的框架(React、Vue、Svelte)契合
- 更适合微前端架构
- 行为更可预测
When to Use Container Queries vs Media Queries
何时使用容器查询 vs 媒体查询
🤔 Use Container Queries when:
- Styling reusable components (cards, widgets, forms)
- Component appears in multiple contexts
- Component needs to adapt to its parent's size
- Building a component library
🤔 Use Media Queries when:
- Changing overall page layout
- Adjusting navigation structure
- Modifying font sizes globally
- Viewport-specific features (like mobile-first approach)
🤔 适合使用容器查询的场景:
- 为可复用组件(卡片、小部件、表单)设置样式
- 组件会出现在多种环境中
- 组件需要根据父容器尺寸自适应
- 构建组件库
🤔 适合使用媒体查询的场景:
- 修改整体页面布局
- 调整导航结构
- 全局修改字体大小
- 视口专属特性(如移动端优先方案)
Requirements
实施要求
What to Do
实施步骤
Review and refactor responsive components to use container queries where appropriate.
审查并重构响应式组件,在合适的场景下使用容器查询。
Implementation Checklist
实施检查清单
1. CSS Implementation
1. CSS实现方式
Step 1: Define the container
css
.component-wrapper {
container-type: inline-size; /* or 'size' for both dimensions */
container-name: myComponent; /* optional but recommended */
}Step 2: Add container queries
css
/* 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)
css
@container (400px <= width <= 800px) {
.component-content {
display: grid;
grid-template-columns: repeat(2, 1fr);
}
}步骤1:定义容器
css
.component-wrapper {
container-type: inline-size; /* or 'size' for both dimensions */
container-name: myComponent; /* optional but recommended */
}步骤2:添加容器查询
css
/* 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;
}
}步骤3:使用现代范围语法(可选)
css
@container (400px <= width <= 800px) {
.component-content {
display: grid;
grid-template-columns: repeat(2, 1fr);
}
}3. Tailwind CSS Implementation
3. Tailwind CSS实现方式
Step 1: Define container with class
@containerhtml
<div class="@container">
<!-- This is now a container context -->
</div>Step 2: Use container query variants
html
<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(256px)@container (width >= 16rem) - -
@2xs(288px)@container (width >= 18rem) - -
@xs(320px)@container (width >= 20rem) - -
@sm(384px)@container (width >= 24rem) - -
@md(448px)@container (width >= 28rem) - -
@lg(512px)@container (width >= 32rem) - -
@xl(576px)@container (width >= 36rem) - -
@2xl(672px)@container (width >= 42rem) - -
@3xl(768px)@container (width >= 48rem) - -
@4xl(896px)@container (width >= 56rem) - -
@5xl(1024px)@container (width >= 64rem) - -
@6xl(1152px)@container (width >= 72rem) - -
@7xl(1280px)@container (width >= 80rem)
📝 Note: These are Tailwind's default breakpoints. You can customize them in (Tailwind v4) using CSS variables or use arbitrary values like for custom container widths.
globals.css@min-[500px]:gridStep 3: Named containers (Tailwind)
html
<!-- Define named container -->
<div class="@container/main">
<!-- Query specific container -->
<div class="@lg/main:grid-cols-3">
<!-- Content -->
</div>
</div>步骤1:使用类定义容器
@containerhtml
<div class="@container">
<!-- This is now a container context -->
</div>步骤2:使用容器查询变体
html
<div class="@container">
<div class="grid @lg:grid-cols-2 @xl:grid-cols-3">
<!-- Responds to container size, not viewport -->
</div>
</div>Tailwind可用容器断点:
- -
@3xs(256px)@container (width >= 16rem) - -
@2xs(288px)@container (width >= 18rem) - -
@xs(320px)@container (width >= 20rem) - -
@sm(384px)@container (width >= 24rem) - -
@md(448px)@container (width >= 28rem) - -
@lg(512px)@container (width >= 32rem) - -
@xl(576px)@container (width >= 36rem) - -
@2xl(672px)@container (width >= 42rem) - -
@3xl(768px)@container (width >= 48rem) - -
@4xl(896px)@container (width >= 56rem) - -
@5xl(1024px)@container (width >= 64rem) - -
@6xl(1152px)@container (width >= 72rem) - -
@7xl(1280px)@container (width >= 80rem)
📝 注意: 这些是Tailwind的默认断点。你可以在(Tailwind v4)中使用CSS变量自定义,或者使用这类任意值来设置自定义容器宽度。
globals.css@min-[500px]:grid步骤3:命名容器(Tailwind)
html
<!-- Define named container -->
<div class="@container/main">
<!-- Query specific container -->
<div class="@lg/main:grid-cols-3">
<!-- Content -->
</div>
</div>4. Common Patterns
4. 常见模式
Pattern 1: Card Component
html
<!-- 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
html
<!-- 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
html
<!-- 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>模式1:卡片组件
html
<!-- 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>模式2:响应式网格
html
<!-- 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>模式3:容器查询与媒体查询结合
html
<!-- 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>5. Review Process
5. 审查流程
✅ Focus on:
- Recently modified components
- Components using media queries for internal layout
- Reusable component patterns
⚠️ Watch out for:
- Overusing container queries (media queries are still needed for layouts)
- Nesting too many containers (can cause confusion)
- Not naming containers when multiple are present
- Fixed heights (let content flow naturally)
❌ Avoid:
- Replacing all media queries with container queries
- Container queries for page-level layouts
- Complex nesting without clear container names
✅ 审查重点:
- 近期修改过的组件
- 使用媒体查询设置内部布局的组件
- 可复用组件模式
⚠️ 注意事项:
- 过度使用容器查询(布局仍需使用媒体查询)
- 嵌套过多容器(易造成混淆)
- 存在多个容器时未命名
- 固定高度(应让内容自然流动)
❌ 避免事项:
- 用容器查询替换所有媒体查询
- 为页面级布局使用容器查询
- 无清晰容器名称的复杂嵌套
6. Testing Checklist
6. 测试检查清单
After implementing container queries:
- Component works in narrow containers (sidebar)
- Component works in wide containers (main content)
- Component works in medium containers (grid cells)
- No layout breaks at container breakpoints
- Content doesn't overflow fixed heights
- Performance is acceptable (container queries are efficient)
实现容器查询后:
- 组件在窄容器(侧边栏)中正常工作
- 组件在宽容器(主内容区)中正常工作
- 组件在中等容器(网格单元)中正常工作
- 容器断点处无布局断裂
- 内容不会溢出固定高度容器
- 性能符合要求(容器查询效率较高)
7. Browser Support
7. 浏览器支持
✅ Supported:
- Chrome 106+
- Edge 106+
- Safari 16+
- Firefox 110+
💡 Tip: For older browsers, use or progressive enhancement:
@supportscss
/* Fallback for older browsers */
.component {
padding: 1rem;
}
/* Enhanced with container queries */
@supports (container-type: inline-size) {
@container (min-width: 400px) {
.component {
padding: 2rem;
}
}
}✅ 支持的浏览器:
- Chrome 106+
- Edge 106+
- Safari 16+
- Firefox 110+
💡 提示:对于旧版浏览器,可使用或渐进式增强方案:
@supportscss
/* Fallback for older browsers */
.component {
padding: 1rem;
}
/* Enhanced with container queries */
@supports (container-type: inline-size) {
@container (min-width: 400px) {
.component {
padding: 2rem;
}
}
}Examples
示例
✅ Good: Component-Based Container Query
✅ 最佳实践:基于组件的容器查询
html
<!-- 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.
html
<!-- 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>优势: 卡片具备独立性,可在任意布局环境中使用。
❌ Bad: Using Media Queries for Component Internals
❌ 错误示例:为组件内部使用媒体查询
html
<!-- 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 breakpoint. Breaks when placed in a sidebar.
mdhtml
<!-- 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>问题: 卡片假设在断点处始终为全屏宽度,放入侧边栏时会出现布局断裂。
md✅ Good: Named Containers for Clarity
✅ 最佳实践:使用命名容器提升清晰度
html
<!-- 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.
html
<!-- 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>优势: 可清晰区分每个查询对应的容器。
Common Mistakes
常见错误
❌ Mistake 1: Using container queries for page layouts
html
<!-- 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
html
<!-- Don't do this -->
<div>
<div class="@lg:grid-cols-2"><!-- Won't work! --></div>
</div>Fix: Always add to the parent.
@container❌ Mistake 3: Fixed heights with responsive content
css
/* Don't do this */
.container {
height: 400px; /* Fixed height */
}
@container (min-width: 600px) {
.content {
columns: 2; /* Text will overflow! */
}
}Fix: Use or let content determine height.
min-height❌ Mistake 4: Too many nested containers
html
<!-- 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.
❌ 错误1:为页面布局使用容器查询
html
<!-- Don't do this -->
<body class="@container">
<main class="@lg:grid @lg:grid-cols-3">修复方案: 为页面级布局使用媒体查询。
❌ 错误2:忘记定义容器
html
<!-- Don't do this -->
<div>
<div class="@lg:grid-cols-2"><!-- Won't work! --></div>
</div>修复方案: 务必在父元素上添加类。
@container❌ 错误3:为响应式内容设置固定高度
css
/* Don't do this */
.container {
height: 400px; /* Fixed height */
}
@container (min-width: 600px) {
.content {
columns: 2; /* Text will overflow! */
}
}修复方案: 使用或让内容决定高度。
min-height❌ 错误4:嵌套过多容器
html
<!-- Don't do this -->
<div class="@container">
<div class="@container">
<div class="@container">
<div class="@lg:..."><!-- Confusing! --></div>
</div>
</div>
</div>修复方案: 使用命名容器并保持浅层级嵌套。
Quick Reference
快速参考
Vanilla CSS
原生CSS
css
/* 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 */
}css
/* 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 */
}Tailwind CSS
Tailwind CSS
html
<!-- 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>html
<!-- 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>