容器查询必须显式启用@container类并配置containers阈值,仅对直接父容器生效,依赖浏览器原生支持,且需确保尺寸基准稳定。

容器查询必须显式启用 @container
默认 Tailwind 不解析 @container 语法,哪怕你写了 @container 或 @sm 前缀,也会被忽略。v4 要求你主动在 HTML 容器上加 @container 类(或自定义类名),并确保父级有尺寸约束——它不是媒体查询的替代品,而是独立的容器作用域开关。
常见错误现象:@sm:grid-cols-2 完全不生效、DevTools 中查不到对应媒体查询规则、子元素响应式类名静默失效。
- 必须写成
<div class="@container">,不能只靠父级 width 或 flex 布局“触发” <li> <code>@container只对**直接父容器**生效,嵌套多层时每一层需单独加(如卡片内再套网格,外层卡片和内层网格都要加) - 父容器若为
flex或grid,需确保它本身有明确宽度(如w-full或max-w-4xl),否则容器查询无基准尺寸可测 - 旧项目升级 v4 后发现失效,大概率是漏了
@container类——它不像md:那样自动注入,必须手写 - 配置示例:
module.exports = { theme: { extend: { containers: { 'sm': '300px', 'md': '600px', 'lg': '900px' } } } } - 别名可任意命名,比如用
@card代替@sm,只要配置里有card: '280px' - 注意:v4 的容器查询依赖浏览器原生支持(Chrome 120+ / Safari 16.4+ / Firefox 128+),低版本会完全跳过整条规则,不降级
- 稳妥做法:给
@container元素加relative和明确min-w-0(防 flex/gird 下内容溢出干扰尺寸计算) - 避免在
@container内部直接写absolute子项;如必须,用inset-0+z-10显式控制层级与占位 -
@container不支持伪元素(::before/::after)触发查询,所有尺寸判断只基于容器盒模型本身 - 写法:
@[200px]:block、@[32rem]:grid-cols-2,不是@200px:block - 配合 JS 使用时,推荐封装成函数生成类名:
const cls = `@[${height}px]:opacity-100`,再传给className - 任意值不参与 PurgeCSS 清理,但过度使用会导致构建体积膨胀——仅在真正需要动态尺寸判断时采用
@sm / @md 等前缀不是断点,而是容器尺寸别名
@sm、@md 不代表视口宽度,而是你配置的容器查询尺寸阈值。Tailwind 默认不预设这些别名,必须在 tailwind.config.js 的 theme.extend.containers 里明确定义,否则 @sm:xxx 会被当作无效类丢弃。
例如想让容器宽 ≥ 300px 时两列布局,但没配 containers.sm,@sm:grid-cols-2 就不会生成任何 CSS。
容器查询 + flex/grid 混用时 display 必须显式声明
当在 @container 内部写 @md:flex-row 或 @lg:grid-cols-3,如果父容器本身是 flex 或 grid,子元素可能因继承 display 而破坏容器查询逻辑——特别是子元素用了 absolute 或 fixed 定位后脱离文档流,容器尺寸检测就失准了。
调试时看 DevTools 的 Layout 面板,确认容器实际渲染宽度是否稳定;若宽度忽大忽小,大概率是子元素撑开或塌陷导致。
动态容器尺寸要用 [size] 任意值语法
预设的 @sm @md 是静态阈值,但真实业务中常需根据组件 props 或数据长度动态调整断点,比如卡片高度随内容增长,希望“高度 > 200px 时显示展开按钮”。这时得用任意值语法绕过配置限制。
注意:方括号内不能有空格,且必须是合法 CSS 尺寸单位(px、rem、em),百分比(%)在容器查询中无效。
flex: 1 拉伸又没设 min-width),整个查询链就断了。上线前务必在 DevTools 里手动拖拽容器尺寸,验证各阈值是否按预期触发。











