关于 prefer-container-queries
这项指导技能帮助编写随容器而非视口变化的 Tailwind 响应式组件,涵盖容器查询的选择、迁移与代码审查。
主要功能
- 01优先采用容器查询
- 02说明 Tailwind 容器变体
- 03指导迁移视口断点
- 04识别常见查询错误
- 05区分视口级布局
适用场景
- 01构建侧边栏和模态框卡片
- 02迁移组件的响应式类
- 03检查窄空间中的布局
安装
复制下面的命令,在终端中运行。
$
npx skills add https:/ / github.com/ flornkm/ skills --skill prefer-container-queries安装后在 Claude Code 中输入/prefer-container-queries确认已加载。
详细介绍
优先使用容器查询
组件应根据所在空间做出响应,而不是根据视口响应。即使屏幕很大,侧边栏中的卡片也可能只有 300px 宽,而像 md:flex-row 这样的视口断点每次都会判断错误。容器查询可以解决这个问题:组件询问“我有多宽?”,而不是“窗口有多宽?”
编写响应式 Tailwind 时,默认使用容器查询。视口断点应是例外,而非规则。
工作原理
将父元素标记为容器,然后在其子元素上使用带 @ 前缀的变体:
<div class="@container">
<div class="flex flex-col @md:flex-row @md:gap-6">
<img class="w-full @md:w-48" />
<div class="@md:flex-1">...</div>
</div>
</div>
这里的 @md: 表示“容器宽度至少为 28rem 时”,与视口尺寸无关。无论卡片位于侧边栏、模态框还是全宽网格中,都无需更改任何类。
有两条容易让人犯错的规则:
@container类应放在父元素上。@md:变体应放在后代元素上。元素不能查询自身的尺寸。- 容器变体会响应最近的带有
@container的祖先。如果样式没有生效,请检查你实际查询的是哪个容器。
变体
Tailwind v4 的核心功能已包含容器查询。各尺寸如下:
| 变体 | 最小宽度 |
|---|---|
@3xs | 16rem(256px) |
@2xs | 18rem(288px) |
@xs | 20rem(320px) |
@sm | 24rem(384px) |
@md | 28rem(448px) |
@lg | 32rem(512px) |
@xl | 36rem(576px) |
@2xl | 42rem(672px) |
@3xl | 48rem(768px) |
@4xl | 56rem(896px) |
@5xl | 64rem(1024px) |
@6xl | 72rem(1152px) |
@7xl | 80rem(1280px) |
此外还提供:
@max-md::容器尺寸小于指定值时应用样式。@min-[475px]::当预设范围不适用时使用任意值。@container/sidebar配合@md/sidebar:flex-row:为容器命名,以便在树结构更深处、越过其他容器查询它。
完整文档请见这里。
在 Tailwind v3 中,相同语法需要使用 @tailwindcss/container-queries 插件。编写类之前请先检查 Tailwind 版本。
何时仍应使用视口断点
以下情况不要改用容器查询:
- 页面级布局。整体网格、侧边栏是否存在、页眉和导航的行为。这些确实取决于视口。
- 相对于视口定位的固定或粘性元素,例如从底部栏变为侧边栏的元素。
- 与屏幕尺寸相关的全局排版比例。
这些布局区域内的所有内容,也就是卡片、表单、媒体对象、统计区块,以及表格与列表之间的切换,都应使用容器查询。
迁移现有代码
- 找出组件的响应式类(
sm:、md:、lg:)。 - 在组件的根元素上,或在负责提供可用空间的包装元素上添加
@container。 - 将视口变体替换为与布局实际应发生变化的宽度相匹配的容器变体。不要盲目地将
md:映射为@md:;md对应 768px 的视口宽度,而@md对应 448px 的容器宽度。调整容器大小而非窗口,找出真正的断点。 - 在组件最狭窄的实际使用场景(侧边栏、抽屉、小网格单元格)中测试,而不只是测试移动端视口宽度。
代码审查时应留意的错误
- 在侧边栏或模态框中的组件上使用
md:flex-row。它会根据视口而非实际可用空间保持堆叠或发生错乱。 - 使用
@md:变体,却没有@container祖先。这些变体会悄无声息地失效。 - 在同一个元素上使用
@container和@md:变体。元素不能查询自身;请将变体移到子元素上,或将容器类移到父元素上。 - 组件只在最初设计的那个确切位置显示正常。如果将它移到另一列就会出错,说明它与视口耦合。
评论
支持 Markdown