PAYATHON 2026

如何在 Tailwind CSS v4 中合并多个 @variant 规则?

技术老齐

可以。Tailwind CSS 从 v4.3.0 起支持 @variant hover:not-focus { … },v4.2 不支持。你尝试的语法在 v4.3 中可以直接使用,无须添加括号或更换分隔符。v4.3.0 更新日志列出了这项功能。

为什么在 v4.2 中无法生效

v4.2 的单条 @variant 只接受一个 variant。utility 中可以使用 hover:not-focus:bg-sky-900,但当时的 @variant 还不支持用冒号组合多个 variant,需要逐层嵌套。支持组合 variants 的变更说明解释了这一限制。

这两个指令的用途也有区别:

  • @variant:在自定义 CSS 中应用已有 variant。
  • @custom-variant:定义新的 variant。

示例里的 @variant hover 就是在应用 hover 条件,官方指令文档也使用了这一术语。

升级到 v4.3 后,直接使用冒号组合

将示例中的浏览器包从 @4.2 改为 @4.3,就可以用一条规则表达组合条件:

<script src="https://cdn.jsdelivr.net/npm/@tailwindcss/browser@4.3"></script>

<style type="text/tailwindcss">
  .example {
    width: --spacing(32);
    height: --spacing(32);
    background-color: var(--color-sky-300);

    @variant hover:not-focus {
      background-color: var(--color-sky-900);
    }
  }
</style>

<input class="example">

这里的冒号表示条件叠加:元素处于 hover 状态且未获得焦点时,才应用深色背景。这与嵌套使用 @variant hover 和 @variant not-focus 的条件相同。官方文档中的 @variant hover:focus 示例也使用了这种语法。

保留 v4.2 时,如何减少重复嵌套

如果只是想缩短当前规则,原来的 @apply 就能表达完整条件:

.example {
  @apply size-32 bg-sky-300 hover:not-focus:bg-sky-900;
}

如果要在多处复用这个条件,并在规则中编写普通 CSS 声明,可以先定义一个命名 variant:

@custom-variant hover-not-focus {
  @media (hover: hover) {
    &:hover:not(:focus) {
      @slot;
    }
  }
}

.example {
  width: --spacing(32);
  height: --spacing(32);
  background-color: var(--color-sky-300);

  @variant hover-not-focus {
    background-color: var(--color-sky-900);
  }
}

@slot 是使用该 variant 时插入样式的位置。组合条件只需定义一次,使用时也只需一层 @variant。自定义 variant 的块语法见官方文档。

注意冒号、逗号和 hover 的含义

在 v4.3 中,冒号和逗号表达的关系不同:

  • @variant hover:not-focus:叠加条件,要求同时满足。
  • @variant hover, not-focus:分别应用两个条件,满足任意一个即可。

这里不能用逗号替代冒号。官方示例说明了这两种用法。

Tailwind 的内置 hover 还包含 @media (hover: hover) 条件。上面的自定义 variant 保留了这个条件;如果只写 &:hover:not(:focus),就会漏掉对设备悬停能力的判断。

测试 <input> 时也要注意焦点状态:鼠标移入且输入框未聚焦时,背景会变深;点击输入框使其获得焦点后,not-focus 条件不再成立,背景就会恢复浅色。

备注:内容仅供参考。