Kodokon kodokon.com

容器查询与 CSS 嵌套

让你的组件响应其容器而非视口,并用原生嵌套来组织你的样式表。

10 分钟 · 3 题

在 Kodokon 中打开本课

媒体查询衡量的是视口:一张既显示在窄侧栏、又显示在主网格里的卡片,无法靠它们正确适配,因为同一个屏幕宽度对应着两种不同的上下文。容器查询解决了这种脱钩:组件查询的是它自己容器的尺寸。前提是:用 container-type 显式指定一个容器(inline-size 只衡量水平轴,这是常见情形),并可选地通过 container-name 命名。

CSS
.sidebar {
  container-type: inline-size;
  container-name: sidebar;
}

@container sidebar (min-width: 400px) {
  .widget {
    display: grid;
    grid-template-columns: 80px 1fr;
    gap: 12px;
  }
}
一个适配其所在列、而非屏幕的小部件

容器单位补全了这幅图景:1cqi 等于被查询容器行内尺寸的 1%(还有 cqwcqhcqbcqmincqmax)。与 clamp() 结合,它们能产生按组件的流式排版:同一张卡片会得到一个与它所在列成比例的标题,无论它被放在哪里。

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

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

@container (max-width: 300px) {
  .card .meta {
    display: none;
  }
}
cqi 单位与不带容器名的查询

原生嵌套终于带来了无需预处理器的嵌套。& 选择器引用父级上下文;媒体查询和 @container 可以直接嵌套在一条规则里。与 Sass 有一个关键区别:嵌套的父级被当作包裹在 :is() 里处理。由此有两个后果:如果父级是一个选择器列表,其特异性就是其中最强者的特异性;而且 & .child 不进行字符串拼接——用于生成 BEM 名称的 Sass &__element 模式在原生里并不存在。

CSS
.menu {
  display: flex;
  gap: 8px;

  & > li {
    list-style: none;

    &:hover {
      background: #f3f4f6;
    }
  }

  @media (min-width: 768px) {
    gap: 16px;
  }
}
原生嵌套:状态、后代与一条媒体查询

知识检测

确认你已牢记本课的重点内容。

  1. 对于一张可复用的卡片,为什么容器查询比媒体查询更可取?
    • 它对渲染引擎来说求值更快
    • 它响应卡片容器的尺寸,而在任何列很窄的屏幕上这个尺寸都是一样的
    • 它无需声明任何 CSS 前提就能工作
    • 除了宽度之外,它还能查询视口的高度
  2. 5cqi 对应什么?
    • 视口宽度的 5%
    • 被查询容器行内尺寸的 5%
    • 容器字号的 5 倍
  3. 原生嵌套与 Sass 嵌套有何不同?
    • 原生嵌套禁止在一条规则内嵌套媒体查询
    • 原生嵌套把父级当作包裹在 :is() 里处理,且不允许 &__element 式的拼接
    • 原生嵌套需要预处理器来编译 & 符号
    • 原生嵌套把嵌套限制在单一层级