CSS 容器查询(@container)的实用案例

在响应式设计领域,媒体查询(@media)长期以来一直是核心工具,但它有一个根本限制——它基于视口(viewport)尺寸而非组件自身的容器尺寸。CSS容器查询(@container)的引入彻底改变了这一局面,使组件能够根据其所在容器的尺寸而非整个视口来调整样式,为前端开发带来了前所未有的灵活性。

容器查询基础

定义容器

要使用容器查询,首先需要将一个元素声明为"容器":

css 复制代码
.component-container {
  container-type: inline-size;
  container-name: component-container;
}

container-type可以是:

  • inline-size:基于内联轴(通常是宽度)查询
  • size:基于宽度和高度查询
  • normal:仅基于样式查询(CSS Level 4)

基本查询语法

css 复制代码
@container component-container (min-width: 600px) {
  .child-element {
    /* 当容器宽度≥600px时的样式 */
  }
}

实用案例解析

案例1:自适应卡片组件

传统卡片组件在不同位置可能需要不同布局,使用容器查询可以完美解决:

css 复制代码
.card-container {
  container-type: inline-size;
}

.card {
  display: flex;
  flex-direction: column;
  gap: 1rem;
}

@container (min-width: 400px) {
  .card {
    flex-direction: row;
  }
  
  .card__image {
    flex: 0 0 150px;
  }
}

@container (min-width: 700px) {
  .card {
    flex-direction: column;
  }
  
  .card__image {
    width: 100%;
    height: 200px;
    object-fit: cover;
  }
}

这种实现允许同一卡片组件在侧边栏(窄容器)中显示为行布局,在主要内容区(中等容器)中显示为列布局,而在全宽容器中显示为特色布局。

案例2:动态导航菜单

导航菜单可以根据可用空间智能调整:

css 复制代码
.nav-container {
  container-type: inline-size;
}

@container (max-width: 500px) {
  .nav-menu {
    flex-direction: column;
  }
  
  .nav-item {
    padding: 0.5rem;
  }
  
  .nav-dropdown {
    position: static;
  }
}

@container (min-width: 501px) and (max-width: 800px) {
  .nav-menu {
    flex-wrap: wrap;
  }
  
  .nav-item {
    flex: 1 0 120px;
  }
}

案例3:响应式网格系统

创建真正自适应的网格布局:

css 复制代码
.grid-container {
  container-type: inline-size;
}

.grid {
  display: grid;
  gap: 1rem;
}

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

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

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

高级技巧与最佳实践

1. 容器查询与CSS自定义属性结合

css 复制代码
:root {
  --card-padding: 1rem;
}

@container (min-width: 400px) {
  .card {
    --card-padding: 1.5rem;
  }
}

.card {
  padding: var(--card-padding);
}

2. 容器查询单位

CSS新增了容器查询单位,使尺寸可以相对于容器:

  • cqw - 容器宽度的1%
  • cqh - 容器高度的1%
  • cqi - 容器内联尺寸的1%
  • cqb - 容器块尺寸的1%
  • cqmin - cqicqb中较小的值
  • cqmax - cqicqb中较大的值
css 复制代码
.card {
  font-size: clamp(1rem, 3cqi, 1.5rem);
}

3. 性能优化

  • 避免过度嵌套容器查询
  • 尽量使用inline-size而非size,除非确实需要高度查询
  • 合理设置断点,避免过多微小变化

浏览器支持与渐进增强

截至2023年,所有现代浏览器都已支持容器查询。对于不支持的环境,可以采用以下策略:

css 复制代码
.card {
  /* 默认移动样式 */
}

@supports (container-type: inline-size) {
  /* 容器查询增强 */
}

/* 或者使用媒体查询作为回退 */
@media (min-width: 600px) {
  /* 桌面布局 - 当容器查询不可用时的回退 */
}

结语

CSS容器查询代表了响应式设计的未来方向,它使组件真正实现了"一次编写,随处适配"的理念。通过将响应逻辑从视口转移到组件容器本身,开发者可以创建更加灵活、可维护的UI系统。随着浏览器支持的完善和开发者经验的积累,容器查询必将成为现代CSS工具箱中不可或缺的一部分。