Tailwind CSS v3.2: Dynamic breakpoints, multi-config, and container queries, oh my!

Adam Wathan
Tailwind CSS v3.2

Tailwind CSS v3.2 已经发布,带来了大量的新功能,包括对动态断点、单个项目中的多个配置文件、嵌套组、参数化变体、容器查询等的支持。

与往常一样,请查看 发行说明 以获取每个细枝末节的修复和改进,但这里是精彩片段:

通过从 npm 安装最新版本的 tailwindcss 来升级您的项目:

npm install -D tailwindcss@latest

或者在 Tailwind Play 中玩转新功能,您可以在浏览器中立即尝试所有功能。


在单个项目中使用 @config 的多个配置文件

我们添加了一个新的 @config 指令,您可以在 CSS 文件中使用它来指定该文件要使用的 Tailwind CSS 配置:

@config "./tailwind.admin.config.js";@tailwind base;@tailwind components;@tailwind utilities;

这使得在单个项目中构建具有独立 Tailwind 配置的多个样式表变得更加容易。例如,您可能有一个配置文件用于网站的客户部分,另一个配置文件用于管理/后台区域。

您一直可以通过足够的 webpack 魔法来做到这一点,但新的 @config 指令使其超级简单且易于访问,即使在您对构建工具配置没有太多控制的项目中也是如此。


使用 supports-* 的基于浏览器支持的样式

您现在可以根据用户浏览器中是否支持某个功能有条件地对元素进行样式设置,使用 supports-[...] 变体,该变体在底层生成 @supports 规则

<div class="flex supports-[display:grid]:grid ...">  <!-- ... --></div>

supports-[...] 变体接受您在方括号中使用的任何内容,例如属性/值对,甚至使用 andor 的表达式。

如果您只需要检查属性本身是否受支持,您甚至可以只指定属性名称,Tailwind 会为您填补空白:

<div class="bg-black/75 supports-[backdrop-filter]:bg-black/25 supports-[backdrop-filter]:backdrop-blur ...">  <!-- ... --></div>

ARIA 属性变体

您现在可以根据 ARIA 属性 有条件地对元素进行样式设置,使用新的 aria-* 变体。

例如,您可以根据 aria-checked 状态是否为 true 来更新元素的背景颜色:

<span class="bg-gray-600 aria-checked:bg-blue-600" aria-checked="true" role="checkbox">  <!-- ... --></span>

默认情况下,我们为最常见的布尔 ARIA 属性包含了修饰符:

修饰符CSS
aria-checked&[aria-checked="true"]
aria-disabled&[aria-disabled="true"]
aria-expanded&[aria-expanded="true"]
aria-hidden&[aria-hidden="true"]
aria-pressed&[aria-pressed="true"]
aria-readonly&[aria-readonly="true"]
aria-required&[aria-required="true"]
aria-selected&[aria-selected="true"]

您可以通过编辑 tailwind.config.js 文件中的 theme.ariatheme.extend.aria 来自定义可用的 aria-* 修饰符:

tailwind.config.js
module.exports = {  theme: {    extend: {      aria: {        asc: 'sort="ascending"',        desc: 'sort="descending"',      },    },  },};

如果您需要使用一个不适合包含在主题中的一次性 aria 修饰符,或者对于需要特定值的更复杂的 ARIA 属性,请使用方括号生成一个使用任意值的属性。

Invoice #ClientAmount
#100Pendant Publishing$2,000.00
#101Kruger Industrial Smoothing$545.00
#102J. Peterman$10,000.25
<table>  <thead>    <tr>      <th        aria-sort="ascending"        class="aria-[sort=ascending]:bg-[url('/img/down-arrow.svg')] aria-[sort=descending]:bg-[url('/img/up-arrow.svg')]"      >        Invoice #      </th>      <!-- ... -->    </tr>  </thead>  <!-- ... --></table>

ARIA 状态修饰符还可以使用 group-aria-*peer-aria-* 修饰符来定位父元素和兄弟元素:

<table>  <thead>    <tr>      <th aria-sort="ascending" class="group">        Invoice #        <svg          class="group-aria-[sort=ascending]:rotate-0 group-aria-[sort=descending]:rotate-180"        >          <!-- ... -->        </svg>      </th>      <!-- ... -->    </tr>  </thead>  <!-- ... --></table>

Data 属性变体

您现在可以根据 data 属性 有条件地对元素进行样式设置,使用新的 data-* 变体。

由于没有标准的 data-* 属性,默认情况下我们只支持任意值,例如:

<!-- 将应用 --><div data-size="large" class="data-[size=large]:p-8">  <!-- ... --></div><!-- 不会应用 --><div data-size="medium" class="data-[size=large]:p-8">  <!-- ... --></div><!-- 生成的 CSS --><style>  .data-\[size\=large\]\:p-8[data-size="large"] {    padding: 2rem;  }</style>

您可以在 tailwind.config.js 文件的 theme 部分下的 data 键中配置项目中常用的数据属性选择器的快捷方式:

// tailwind.config.jsmodule.exports = {  theme: {    data: {      checked: 'ui~="checked"',    },  },  // ...};
<div data-ui="checked active" class="data-checked:underline">  <!-- ... --></div>

这些变体还可以像框架中的许多其他变体一样作为 group-*peer-* 变体工作:

<div data-size="large" class="group">  <div class="group-data-[size=large]:p-8">    <!-- 将应用 `p-8` -->  </div></div><div data-size="medium" class="group">  <div class="group-data-[size=large]:p-8">    <!-- 不会应用 `p-8` -->  </div></div>

最大宽度和动态断点

我们添加了一个新的 max-* 变体,允许您根据配置的断点应用最大宽度媒体查询:

<div class="max-lg:p-8">  <!-- 将应用 `p-8` 直到 `lg` 断点生效 --></div>

作为一般规则,我个人仍然建议使用最小宽度断点,但此功能确实解锁了一个有用的工作流程优势,即不必在不同的断点撤销某些样式。

例如,没有此功能,您通常会这样做:

<div class="md:sr-only xl:not-sr-only">  <!-- ... --></div>

有了这个功能,您可以通过在原始声明上堆叠一个 max-* 变体来避免撤销该样式:

<div class="md:max-xl:sr-only">  <!-- ... --></div>

除此之外,我们还添加了对任意值的支持,以及一个新的 min-* 变体,该变体仅接受任意值,因此您可以执行以下操作:

<div class="min-[712px]:max-[877px]:right-16 ...">  <!-- ... --></div>

重要的是要注意,这些功能仅在您的项目使用简单的 screens 配置时可用。

由于需要确保所有这些媒体查询在最终 CSS 中按顺序排列,以便在浏览器中获得预期的行为,这些功能比看起来要复杂得多。因此,目前,它们仅在您的 screens 配置是一个简单的对象并且具有字符串值时才有效,例如默认配置:

// tailwind.config.jsmodule.exports = {  theme: {    screens: {      sm: "640px",      md: "768px",      lg: "1024px",      xl: "1280px",      "2xl": "1536px",    },  },};

如果您有一个复杂的配置,其中已经定义了 max-width 断点,或基于范围的媒体查询,或除了字符串之外的任何内容,这些功能将不可用。我们可能会在未来解决这个问题,但它确实会引发许多关于 CSS 应该如何排序的问题,我们目前还没有答案。

因此,目前(也可能永远),如果您想使用这些功能,您的 screens 配置需要简单。我的希望是这些功能使复杂的 screens 配置变得不必要。


动态 group-* 和 peer-* 变体

现在可以通过传递自己的选择器来动态创建 group-*peer-* 变体,在方括号之间进行“分组化”或“对等化”:

<div class="group is-published">  <div class="group-[.is-published]:block hidden">Published</div></div>

为了获得更多控制,您可以使用 & 字符来标记 .group.peer 在最终选择器中相对于您传入的选择器的位置:

<div>  <input type="text" class="peer" />  <div class="peer-[:nth-of-type(3)_&]:block hidden">    <!-- ... -->  </div></div>

让我们认真点,您可能一生中只会使用这些功能三次,但它仍然非常酷。希望我们可以将其用作构建块,以使 grouppeer 在未来更自动地与第三方插件注册的变体一起工作。


使用 matchVariant 的动态变体

您可能已经注意到这些新功能中的许多都使用了新的 variant-[...] 语法——这都是由新的 matchVariant 插件 API 提供支持的,该 API 使创建我们称之为“动态变体”的功能成为可能。

以下是为某个使用 data-placement 属性告诉您工具提示当前定位位置的虚构工具提示库创建 placement-* 变体的示例:

let plugin = require("tailwindcss/plugin");module.exports = {  // ...  plugins: [    plugin(function ({ matchVariant }) {      matchVariant(        "placement",        (value) => {          return `&[data-placement=${value}]`;        },        {          values: {            t: "top",            r: "right",            b: "bottom",            l: "left",          },        },      );    }),  ],};

上面定义的变体将为您提供 placement-tplacement-b 等变体,但也支持方括号中的任意部分,因此如果这个虚构的工具提示库有其他潜在值,您不觉得需要为其创建内置值,您仍然可以做这样的事情:

<div class="placement-[top-start]:mb-2 ...">  <!-- ... --></div>

在使用此 API 定义自定义变体时,通常很重要的一点是,您可以控制生成 CSS 的顺序,以确保每个类在与同一变体的其他值相关的情况下具有正确的优先级。为此,您可以在定义变体时提供一个 sort 函数:

matchVariant("min", (value) => `@media (min-width: ${value})`, {  sort(a, z) {    return parseInt(a) - parseInt(z);  },});

使用变体修饰符的嵌套 group 和多个 peer 支持

当您在彼此嵌套的多个 group 块时,有时会遇到问题,因为 Tailwind 没有真正的方法来区分它们。

为了解决这个问题,我们添加了对 变体修饰符 的支持,这是一种新的动态块,您可以将其添加到变体的末尾(受我们的可选不透明度修饰符语法的启发),您可以使用它为每个组/对等体提供自己的标识符。

以下是它的外观:

<div class="group/sidebar ...">  <!-- ... -->  <div class="group/navitem ...">    <a href="#" class="opacity-50 group-hover/navitem:bg-black/75 group-hover/sidebar:opacity-75">      <!-- ... -->    </a>  </div>  <!-- ... --></div>

这使您可以为每个组动态地提供一个清晰的名称,使其在该上下文中有意义,并且 Tailwind 将生成必要的 CSS 以使其工作。

我真的很高兴能为此提供一个解决方案,因为这是我多年来一直在尝试找到一个好的解决方法的东西,这是我们提出的第一个真正感觉提供了我认为应该具备的功能和灵活性的东西。


容器查询

我几乎不敢相信,但 容器查询 终于成为现实,并且浏览器支持已经非常接近使这些功能可以投入生产——事实上,如果您正在构建 Electron 应用程序,您今天就可以使用这些功能。

今天我们发布了 @tailwindcss/container-queries,这是一个新的官方插件,向框架添加了容器查询支持,使用新的 @ 语法将其与普通媒体查询区分开来:

<div class="@container">  <div class="block @lg:flex">    <!-- ... -->  </div></div>

开箱即用,我们包括了一组与默认 max-width 规模匹配的容器大小:

名称
xs20rem
sm24rem
md28rem
lg32rem
xl36rem
2xl42rem
3xl48rem
4xl56rem
5xl64rem
6xl72rem
7xl80rem

您可以使用 tailwind.config.js 文件中的 containers 键配置可用的值:

// tailwind.config.jsmodule.exports = {  theme: {    extend: {      containers: {        2xs: '16rem',        // etc...      },    },  },};

我们还包括对任意值的支持,使用 @[...] 语法:

<div class="@container">  <div class="block @[618px]:flex">    <!-- ... -->  </div></div>

...以及使用我们现在为 group-*peer-* 变体提供的相同变体修饰符语法的命名容器:

<div class="@container/main">  <!-- ... -->  <div>    <div class="block @lg/main:flex">      <!-- ... -->    </div>  </div></div>

目前我们从简单的基于最小宽度的容器查询开始,但我们计划随着时间的推移扩大范围,当我们觉得已经真正掌握了 API 时,我们会将其全部引入核心。

有关完整文档,请查看插件 在 GitHub 上


所以这就是 Tailwind CSS v3.2!重大改进,但只是一个小版本更改,因此没有重大更改,您应该能够通过更新依赖项来更新项目:

npm install -D tailwindcss@latest

是的,我听到你在后面说,仍然没有文本阴影,但嘿,至少你可以在不离开 HTML 的情况下为复选框的父元素是列表中的第三个子元素时的兄弟元素设置样式。优先级问题。

Get all of our updates directly to your inbox.
Sign up for our newsletter.