CSS 容器查询怎么用?和媒体查询有什么区别

juming
juming 正式会员超兽战士
发布于 2026-10-07 15:23 ·1 浏览 ·0 回复

媒体查询看的是视口(viewport)宽度,容器查询看的是元素所在的父容器宽度——所以媒体查询适合页面级布局,容器查询适合组件级自适应。截至 2023 年 2 月(Chrome 105 / Safari 16.0 / Firefox 110),@container 已在所有主流浏览器可用,可以直接上生产。

媒体查询和容器查询到底有什么区别?

结论:媒体查询的判定依据是设备和视口,与元素在页面里的位置无关;容器查询的判定依据是最近的、被声明为容器的祖先元素的尺寸。

具体差异有 4 点:

  • 判定对象:@media (min-width: 768px) 只看浏览器窗口;@container (min-width: 480px) 看父容器的实际渲染宽度。
  • 是否影响自身:媒体查询可以作用在任意元素上,包括容器自己;容器查询不能查询容器自身,只能作用在它的后代元素上。
  • 复用性:同一个卡片组件放在侧栏(宽 300px)和主区(宽 700px),媒体查询无法区分(视口一样),容器查询能自动切换布局。
  • 前置条件:容器查询必须先给祖先元素加 container-type,媒体查询不需要任何声明。

容器查询怎么用?三步搞定

结论:给父元素声明 container-type,给子元素写 @container 规则,浏览器就会按父容器的宽度切换样式。

第一步,在容器上声明:

.card-wrap {
  container-type: inline-size;   /* 只关心 inline 轴(横向)尺寸 */
  container-name: card;          /* 命名,便于精确指定 */
  /* 简写:container: card / inline-size; */
}

第二步,在后代元素上查询:

@container card (min-width: 480px) {
  .card {
    display: grid;
    grid-template-columns: 120px 1fr;
    gap: 16px;
  }
}

@container card (max-width: 479px) {
  .card img { width: 100%; }
}

第三步(可选),做降级兜底:

@supports (container-type: inline-size) {
  /* 支持容器查询时的增强样式 */
}

注意点有两个:container-type: inline-size 会开启 inline 轴尺寸隔离(元素横向尺寸不再由内容决定),所以别在指望被内容撑开的元素上乱加;container-type: size 要求两个方向都有确定尺寸,通常更麻烦,能用 inline-size 就别用 size。

为什么容器不能查询自己?

结论:因为 container-type 会触发尺寸包含(containment),此时容器的宽度由外部决定、与内容无关,若再允许它查询自己就会形成循环依赖,浏览器只能规定「容器查询只对后代生效」。

所以正确写法是「外层包一层容器,内层写查询」:

<div class="card-wrap">
  <div class="card">...</div>
</div>

如果直接给 .card 加 container-type 再写 @container (min-width: 480px) .card {},这条规则永远不会生效——这是新手最常见的坑。

容器查询单位怎么用?

结论:cqw、cqh、cqi、cqb、cqmin、cqmax 六个单位分别对应最近查询容器的宽、高、inline 轴、block 轴、较小值、较大值,1cqw = 容器宽度的 1%。

典型用法是流式字号:

.card h2 {
  font-size: clamp(1rem, 4cqw, 1.75rem);
}

这样卡片在 300px 宽的侧栏里标题是 16px 左右,放到 700px 宽的主区域自动涨到 24px,不需要写任何断点。

什么时候该用媒体查询、什么时候用容器查询?

结论:页面骨架、导航折叠、字号根值、打印样式、prefers-reduced-motion(减弱动画偏好)用媒体查询;卡片、列表项、按钮组、侧边栏组件用容器查询。

一句话判断法:**样式变化只取决于「屏幕多宽」时用 @media,取决于「这块地方多宽」时用 @container**。两者不是替代关系,实际项目里通常同时存在:@media 控制在 768px 时页面从单列变两列,@container 控制卡片在窄栏里竖排、宽栏里横排。

另外,@container style(--theme: dark) 这种样式查询(按自定义属性值切换)在 Chrome 111+ 和 Safari 18+ 已支持,Firefox 还没跟上,用之前先确认目标浏览器。

全文要点收束:容器查询的核心是三步——祖先声明 container-type: inline-size、后代写 @container、必要时用 @supports 兜底;它弥补了媒体查询「只认视口、不认组件上下文」的短板,而媒体查询依然负责页面级和设备能力级的判断。组件级自适应优先选 @container,页面级布局继续用 @media。

版权声明:本文来自 GJ站长论坛《CSS 容器查询怎么用?和媒体查询有什么区别》
原文链接:https://www.gj0.com/thread-367.html
转载请注明出处并保留本声明;内容仅代表作者观点,与本站立场无关。若本文涉嫌侵权,请联系本站处理。

全部回复 0

还没有回复,来抢沙发~