Skip to content

2026 年现代 CSS:容器查询、:has() 和锚点定位

今天的 CSS 在复杂布局方面不输 JavaScript。三个最改变界面开发的功能的实用指南。

1 分钟 · 4,701 次阅读
SSSLab

多年来,“如何在 CSS 中做 X?“的答案是”用 JavaScript”。2026 年这个答案对大多数情况都不再适用。三个特定功能重新绘制了浏览器设计的版图。

目录

容器查询:响应容器,而非屏幕

媒体查询响应的是 viewport 的宽度。问题在于:一个组件可能根据父布局存在于窄列或宽列中。容器查询解决了这个问题。

/* 声明容器 */
.card-wrapper {
  container-type: inline-size; 
  container-name: card;
}

/* 组件响应其容器 */
@container card (min-width: 400px) {
  .card {
    display: grid;
    grid-template-columns: 200px 1fr;
  }

  .card__image {
    grid-row: 1 / 3;
  }
}

@container card (max-width: 399px) {
  .card {
    display: flex;
    flex-direction: column;
  }
}card.css
<!-- 同一组件在任何上下文中都能工作 -->
<aside class="card-wrapper" style="width: 300px">
  <article class="card">...</article>
  <!-- 垂直布局 -->
</aside>

<main class="card-wrapper" style="width: 700px">
  <article class="card">...</article>
  <!-- 水平布局 -->
</main>card.html

容器查询单位

查询也暴露了相对于容器的单位:

.card__title {
  font-size: clamp(1rem, 4cqi, 2rem); /* cqi = 容器查询内联大小 */
}typography.css

:has() 伪类——我们一直想要的父选择器

:has() 根据元素的后代来选择它。这是 CSS 数十年来拒绝的”父选择器”。

/* 有必填字段为空的表单 */
form:has(input:required:invalid) .submit-btn {
  opacity: 0.5;
  pointer-events: none;
}

/* 包含图片的 Card:不同布局 */
.card:has(img) {
  display: grid;
  grid-template-columns: 150px 1fr;
}

.card:not(:has(img)) {
  padding: 1.5rem;
}

/* 导航菜单打开时:禁用 body 滚动 */
body:has(.nav-menu[aria-expanded="true"]) {
  overflow: hidden;
}styles.css

:has() 自 2023 年起被所有现代浏览器支持。你今天可以在生产环境中使用它,无需 polyfills。

锚点定位:无 JavaScript 的工具提示和弹出框

在锚点定位之前,将工具提示相对于其触发器放置需要用 JavaScript 计算位置。现在不需要了:

/* 声明锚点 */
.btn-trigger {
  anchor-name: --mi-boton; 
}

/* 相对于锚点定位工具提示 */
.tooltip {
  position: absolute;
  position-anchor: --mi-boton; 
  bottom: calc(anchor(top) + 8px); 
  left: anchor(center); 
  transform: translateX(-50%);

  /* 如果放不下则自动翻转 */
  position-try-fallbacks: flip-block; 
}tooltip.css
<button class="btn-trigger" popovertarget="tip">Hover me</button>
<div id="tip" class="tooltip" popover>
  这个工具提示自己定位,无需 JS。
</div>tooltip.html

position-try-fallbacks:声明式碰撞逻辑

.tooltip {
  position-try-fallbacks:
    flip-block,
    /* 如果下方放不下则尝试上方 */ flip-inline,
    /* 如果右方放不下则尝试左方 */ flip-start; /* 组合两者 */
}tooltip.css

支持情况如何?

功能ChromeFirefoxSafari
容器查询105+ ✓110+ ✓16+ ✓
:has()105+ ✓121+ ✓15.4+ ✓
锚点定位125+ ✓131+ ✓18+ ✓

到 2026 年,根据当前的浏览器分布,你可以对大多数项目在生产环境中使用这三个功能。只有当你的受众包含非常老的浏览器时才考虑 polyfills。

今天的 CSS 是声明式的和表达性的

CSS 的静默革命不是 Grid 也不是 Flexbox。是思维模式的转变:浏览器推理约束,你声明期望的结果。容器查询、:has() 和锚点定位是这种范式的巅峰。

Anterior
2026 年 Docker Compose:真正重要的最佳实践
Siguiente
React 19:useActionState、useOptimistic 以及手动加载状态的终结