Featured image of post 使用 CSS 容器查询设计模块化布局Featured image of post 使用 CSS 容器查询设计模块化布局

使用 CSS 容器查询设计模块化布局

了解如何使用 CSS 容器查询 (@container) 根据父元素而不是视口尺寸构建响应式布局。

介绍

多年来,媒体查询 (@media) 一直是响应式网页设计的基础。

媒体查询根据浏览器窗口的视口宽度触发布局更改。然而,在现代组件驱动开发(使用 React、Vue 或 Web Components)中,基于视口的样式组件有明显的局限性。

例如,如果您想在较宽的主列和较窄的侧边栏中重复使用卡片组件,则媒体查询无法检测到该组件的可用空间,从而导致布局中断。

CSS 容器查询 (@container) 通过允许您相对于其父容器的宽度设置组件的样式来解决此限制。本文介绍容器查询的基础知识以及如何应用它们。


1. 视口与容器查询

基于视口的媒体查询

当浏览器窗口调整大小时,页面上每个与视口链接的元素都会同时改变布局样式。

  • 问题: 组件样式取决于整个窗口宽度,无论其在页面上的位置如何。这会阻止您构建独立的模块化 UI 元素。

基于容器的查询

根据直接父容器的**宽度应用样式。

  • 好处: 当放置在宽的主列中时,卡片组件可以自动呈现水平网格布局,并在移动到狭窄的侧边栏中时交换到堆叠的垂直列表布局 - 所有这些都在 CSS 中本地管理。

2. 基本设置和语法

实现容器查询需要在 CSS 中执行两个步骤:

  1. 将父元素注册为包含查询目标 (container-type)。
  2. 使用 @container 指令为子元素编写样式规则。

HTML结构

<!-- The Parent Container -->
<div class="card-wrapper">
  <!-- The Self-Contained Card Component -->
  <div class="my-card">
    <img src="thumb.jpg" alt="Thumbnail" class="card-img" />
    <div class="card-content">
      <h3>Article Title</h3>
      <p>Brief article excerpt or description text goes here...</p>
    </div>
  </div>
</div>

CSS 实现

/* 1. Register the parent element as a container query context */
.card-wrapper {
  /* Monitor the inline size (width) of the parent element */
  container-type: inline-size;
  /* Optional: Name the container context to target specific elements */
  container-name: card-container;
}

/* Default mobile/stacked card styles */
.my-card {
  display: flex;
  flex-direction: column; /* Stack vertically */
  gap: 15px;
}

/* 2. Style updates when the parent container exceeds 400px wide */
@container (min-width: 400px) {
  .my-card {
    flex-direction: row; /* Switch to horizontal row */
    align-items: center;
  }
  .card-img {
    width: 150px;
    height: 100px;
  }
}

通过此配置,只要 .card-wrapper 宽度超过 400 像素,无论浏览器窗口的整体大小如何,卡片都会切换到水平布局。


3.容器查询单元(cqw、cqh)

容器查询还根据父容器的尺寸引入新的 CSS 单元:

  • cqw:容器宽度的 1%。
  • cqh:容器高度的 1%。
  • cqmincqwcqh 中较小的值。
  • cqmaxcqwcqh 中的较大值。

这些单位对于根据组件的大小动态缩放版式非常有用:

.card-content h3 {
  /* Scale font size based on 5% of the parent container's width */
  font-size: clamp(1rem, 5cqw, 2rem);
}

结论和浏览器支持

所有现代浏览器都支持 CSS 容器查询,包括 Chrome、Safari、Edge 和 Firefox。

使用容器查询可以让您:

  1. 减少对复杂视口媒体查询的依赖。
  2. 构建适应不同布局的可重用 UI 组件。
  3. 使用父容器单元 (cqw) 动态缩放版式。

考虑在 CSS 架构中采用容器查询来构建更加模块化和可维护的响应式设计。