引言

CSS容器查询(Container Queries)是CSS布局领域的革命性特性,它允许我们根据父容器的尺寸而不是视口尺寸来应用样式。这彻底改变了响应式设计的方式,使组件级响应式成为可能。

一、容器查询的核心概念

1.1 什么是容器查询

容器查询是一种CSS机制,允许元素根据其父容器的尺寸来应用样式,而不是依赖于视口尺寸。

.card {
  container-type: inline-size;
  container-name: card;
}

@container card (min-width: 300px) {
  .card-content {
    display: flex;
    gap: 1rem;
  }
}

1.2 与媒体查询的区别

特性 媒体查询 容器查询
参照对象 视口(viewport) 父容器
适用范围 全局布局 组件级布局
触发条件 浏览器窗口大小 容器尺寸变化
使用场景 页面级响应式 组件自适应

1.3 容器查询的组成部分

容器查询由三个核心部分组成:

  1. 容器类型(container-type) - 定义容器的维度
  2. 容器名称(container-name) - 为容器命名
  3. @container规则 - 根据容器尺寸应用样式

二、容器类型详解

2.1 container-type属性

container-type属性定义了容器的查询维度:

/* 块级维度(高度和宽度) */
.container {
  container-type: size;
}

/* 内联维度(宽度) */
.container {
  container-type: inline-size;
}

/* 样式容器 */
.container {
  container-type: style;
}

/* 无容器查询 */
.container {
  container-type: normal;
}

2.2 container-name属性

为容器命名以便在@container规则中引用:

.card {
  container-type: inline-size;
  container-name: card-container;
}

@container card-container (min-width: 400px) {
  /* 针对名为card-container的容器应用样式 */
}

2.3 简写语法

使用container属性同时设置类型和名称:

.card {
  container: card-container / inline-size;
}

三、@container规则深度解析

3.1 基本语法

@container <容器名称> <条件> {
  /* 样式规则 */
}

/* 示例 */
@container card (min-width: 300px) {
  .title {
    font-size: 1.5rem;
  }
}

3.2 可用条件

容器查询支持多种条件类型:

/* 宽度条件 */
@container (min-width: 200px) { }
@container (max-width: 400px) { }

/* 高度条件 */
@container (min-height: 200px) { }
@container (max-height: 400px) { }

/* 内联尺寸条件 */
@container (min-inline-size: 200px) { }
@container (max-inline-size: 400px) { }

/* 块级尺寸条件 */
@container (min-block-size: 200px) { }
@container (max-block-size: 400px) { }

/* 方向条件 */
@container (orientation: landscape) { }
@container (orientation: portrait) { }

/* 组合条件 */
@container (min-width: 300px) and (max-width: 600px) { }

3.3 匿名容器

如果容器没有命名,可以使用匿名容器查询:

.card {
  container-type: inline-size;
}

@container (min-width: 300px) {
  .card-content {
    flex-direction: row;
  }
}

四、实战案例:响应式卡片组件

4.1 基础卡片布局

<div class="card">
  <img src="image.jpg" alt="Card image" class="card-image">
  <div class="card-body">
    <h3 class="card-title">卡片标题</h3>
    <p class="card-text">卡片内容描述文字</p>
    <button class="card-button">了解更多</button>
  </div>
</div>
.card {
  container-type: inline-size;
  container-name: card;
  border-radius: 12px;
  overflow: hidden;
  box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
}

.card-image {
  width: 100%;
  height: 180px;
  object-fit: cover;
}

.card-body {
  padding: 1rem;
}

.card-title {
  font-size: 1.25rem;
  margin-bottom: 0.5rem;
}

.card-text {
  font-size: 0.875rem;
  color: #666;
  margin-bottom: 1rem;
}

.card-button {
  width: 100%;
  padding: 0.5rem 1rem;
  background: #007bff;
  color: white;
  border: none;
  border-radius: 4px;
  cursor: pointer;
}

4.2 添加容器查询

@container card (min-width: 350px) {
  .card {
    display: flex;
  }
  
  .card-image {
    width: 150px;
    height: auto;
    flex-shrink: 0;
  }
  
  .card-body {
    display: flex;
    flex-direction: column;
    justify-content: space-between;
  }
  
  .card-button {
    align-self: flex-start;
    width: auto;
  }
}

@container card (min-width: 500px) {
  .card-title {
    font-size: 1.5rem;
  }
  
  .card-text {
    font-size: 1rem;
  }
  
  .card-image {
    width: 200px;
  }
}

4.3 嵌套容器查询

容器查询可以嵌套使用,创建更复杂的响应式布局:

.card-grid {
  container-type: inline-size;
  container-name: grid;
  display: grid;
  gap: 1rem;
}

@container grid (min-width: 600px) {
  .card-grid {
    grid-template-columns: repeat(2, 1fr);
  }
  
  @container card (min-width: 250px) {
    .card-title {
      font-size: 1.125rem;
    }
  }
}

@container grid (min-width: 900px) {
  .card-grid {
    grid-template-columns: repeat(3, 1fr);
  }
}

五、样式容器(Style Containers)

5.1 什么是样式容器

样式容器允许根据父元素的CSS属性值来应用样式:

.card {
  container-type: style;
  --accent-color: #007bff;
}

@container style(--accent-color: #007bff) {
  .card-button {
    background-color: #007bff;
  }
}

@container style(--accent-color: #28a745) {
  .card-button {
    background-color: #28a745;
  }
}

5.2 动态主题切换

.card {
  container-type: style;
  --theme: light;
}

.card.dark {
  --theme: dark;
}

@container style(--theme: dark) {
  .card {
    background-color: #1a1a1a;
    color: white;
  }
  
  .card-text {
    color: #aaa;
  }
}

六、容器查询单位

6.1 容器相对单位

CSS引入了新的容器相对单位:

单位 含义
cqw 容器宽度的1%
cqh 容器高度的1%
cqi 容器内联轴长度的1%
cqb 容器块轴长度的1%
cqmin min(cqi, cqb)
cqmax max(cqi, cqb)

6.2 使用示例

.card-title {
  font-size: max(1rem, 4cqw);
}

.card-image {
  height: 30cqh;
}

.card-body {
  padding: 2cqw;
}

七、最佳实践与性能优化

7.1 性能考虑

虽然容器查询很强大,但过度使用可能影响性能:

/* 避免:过多的容器查询会增加计算开销 */
.card {
  container-type: inline-size;
}

/* 推荐:仅在需要时使用 */
@media (min-width: 768px) {
  .card {
    container-type: inline-size;
  }
}

7.2 渐进增强策略

为不支持容器查询的浏览器提供降级方案:

.card-content {
  display: block;
}

@supports (container-type: inline-size) {
  .card {
    container-type: inline-size;
  }
  
  @container (min-width: 300px) {
    .card-content {
      display: flex;
    }
  }
}

7.3 调试技巧

使用浏览器开发者工具检查容器查询:

.card::before {
  content: "当前容器宽度: " attr(data-container-width);
  display: block;
  font-size: 0.75rem;
  color: #999;
}

八、浏览器兼容性

8.1 当前支持情况

浏览器 版本支持
Chrome 105+
Firefox 110+
Safari 16+
Edge 105+

8.2 降级方案

使用PostCSS插件或JavaScript polyfill:

npm install @tailwindcss/vite @tailwindcss/container-queries

九、总结

容器查询是CSS响应式设计的重大进步,它使组件级响应式布局成为现实。通过容器查询,我们可以:

  1. 创建真正可复用的响应式组件
  2. 实现更细粒度的布局控制
  3. 构建更灵活的设计系统

掌握容器查询,将使你的CSS技能提升到一个新的水平,让你能够构建更强大、更灵活的前端布局。

关键要点:

  • 使用container-type定义容器维度
  • 使用container-name为容器命名
  • 通过@container规则应用条件样式
  • 结合容器相对单位(cqw, cqh等)实现自适应
  • 使用@supports进行特性检测
  • 注意性能优化,避免过度使用
Logo

AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。

更多推荐