Tailwind CSS v3.4: Dynamic viewport units, :has() support, balanced headlines, subgrid, and more

Adam Wathan
Tailwind CSS v3.4

没有什么比构建一个主要新产品来发现你希望在自己的工具中拥有的所有功能更好的了,所以我们利用其中的一些灵感,并将其变成了这个——Tailwind CSS v3.4。

与往常一样,改进范围从您多年来一直感到愤怒的事情,到支持您甚至从未听说过甚至可能无法在工作中使用的 CSS 功能。

所有好东西都在该列表中,但请查看发行说明,了解一些不够令人兴奋而无法在此帖子中占据一席之地的更多详细信息。

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

npm install tailwindcss@latest

或者在浏览器中直接在 Tailwind Play 上试用所有新功能。


动态视口单位

vh 单位被添加到浏览器时,我们都非常兴奋——终于有了一种方法可以构建全高的应用程序布局,而无需通过 17 层 DOM 进行 height: 100% 的钻取!但移动设备及其该死的消失菜单栏破坏了所有乐趣,实际上使 vh 单位成为一个残酷的提醒,提醒我们本可以如此美好的未来。

好吧,我们现在有了一个新的未来——dvhlvhsvh 旨在适应消失的浏览器界面,Tailwind CSS v3.4 开箱即支持它们:

Scroll up and down in the viewport to hide/show the browser UI

tailwindcss.com

h-dvh

<div class="h-dvh">  <!-- ... --></div>

我们默认添加了以下新类:

CSS
h-svhheight: 100svh
h-lvhheight: 100lvh
h-dvhheight: 100dvh
min-h-svhmin-height: 100svh
min-h-lvhmin-height: 100lvh
min-h-dvhmin-height: 100dvh
max-h-svhmax-height: 100svh
max-h-lvhmax-height: 100lvh
max-h-dvhmax-height: 100dvh

如果您需要其他值,也可以使用任意值,例如 min-h-[75dvh]

如今,这些的浏览器支持非常好,因此除非您需要支持 Safari 14,否则您可以立即开始使用这些。


新的 :has() 变体

:has() 伪类 是自 flexbox 以来添加到 CSS 中的最强大的东西。 有史以来第一次,您可以根据元素的 子元素 设置元素的样式,而不仅仅是根据其父元素。 它甚至可以根据后续兄弟姐妹设置样式。

这是一个示例,其中父元素在其中的单选按钮被选中时会获得彩色环:

支付方式
<label class="has-[:checked]:bg-indigo-50 has-[:checked]:text-indigo-900 has-[:checked]:ring-indigo-500 ...">  <svg fill="currentColor">    <!-- ... -->  </svg>  Google Pay  <input type="radio" class="accent-indigo-500 ..." /></label>

在过去的几个月里,我每周都会发现 :has() 的新用例,并且它取代了我们代码中大量的 JavaScript。

例如,我们的文本输入在设计上非常复杂,需要一个小的包装元素来构建。 没有 :has(),我们无法根据输入的 :disabled 状态设置包装器的样式,但现在我们可以了:

input.jsx
export function Input({ ... }) {  return (    <span className="has-[:disabled]:opacity-50 ...">      <input ... />    </span>  )}

这个功能非常前沿,但截至今天,它现在在所有主要浏览器的最新版本中都受支持。 给 Firefox 用户几周时间来安装今天的更新,我们应该可以尽情使用它。


使用 * 变体设置子元素的样式

这是人们一直想要的——一种使用实用程序类从父元素设置子元素样式的方法。

我们添加了一个新的 * 变体,它会针对直接子元素,让您可以做这样的事情:

类别

销售
市场营销
SEO
分析
设计
策略
安全
增长
移动
UX/UI
<div>  <h2>类别:<h2>  <ul class="*:rounded-full *:border *:border-sky-100 *:bg-sky-50 *:px-2 *:py-0.5 dark:text-sky-300 dark:*:border-sky-500/15 dark:*:bg-sky-500/10 ...">    <li>销售</li>    <li>市场营销</li>    <li>SEO</li>    <!-- ... -->  </ul></div>

通常我建议直接设置子元素的样式,但当您无法控制这些元素或需要根据元素使用的上下文进行条件调整时,这会很有用。

它也可以与其他变体组合,例如 hover:*:underline 将在子元素悬停时设置任何子元素的样式。

这是我们在新 UI 工具包中使用它的一种很酷的方式,用于有条件地向不同的子元素添加布局样式:

JSX
function Field({ children }) {  return (    <div className="data-[slot=description]:*:mt-4 ...">      {children}    </div>  )}function Description({ children }) {  return (    <p data-slot="description" ...>{children}</p>  )}function Example() {  return (    <Field>      <Label>名字</Label>      <Input />      <Description>请告诉我你知道自己的名字。</Description>    </Field>  )}

看到那个疯狂的 data-[slot=description]:*:mt-4 类了吗? 它首先针对所有直接子元素(即 *: 部分),然后使用 data-[slot=description] 将它们过滤到仅具有 data-slot="description" 属性的项目。

这使得只针对特定子元素变得容易,而无需完全降到原始任意变体。

期待看到大家做的所有可怕的事情,让我后悔添加这个功能。


新的 size-* 实用程序

你厌倦了每次需要调整头像大小时都要输入 h-5 w-5,你知道我也知道。

在 Tailwind CSS v3.4 中,我们终于添加了一个新的 size-* 实用程序,可以同时设置宽度和高度:

HTML
<div>  <img class="h-10 w-10" ...>  <img class="h-12 w-12" ...>  <img class="h-14 w-14" ...>  <img class="size-10" ...>  <img class="size-12" ...>  <img class="size-14" ...></div>

我们一直想添加这个功能,但总是纠结于确切的名称——size-* 感觉比 w-*h-* 要多打很多字,而 s-* 又显得太过隐晦。

不过在使用了几周之后,我可以肯定地说,即使名称更长,它也比单独的宽度和高度实用程序要好得多。 非常方便,尤其是当您将其与变体组合或使用复杂的任意值时。


使用 text-wrap 实用程序平衡标题

你花了多少时间调整 max-width 或插入响应式换行符,以尝试使那些小节标题在你的着陆页上漂亮地换行? 现在你可以花零时间了,因为浏览器可以为你完成这项工作,使用 text-wrap: balance

受欢迎的曼哈顿汤摊关闭

纽约人今年冬天面临着更少的温暖,因为该市最受尊敬的汤摊意外关闭,导致社区困惑不解。

<article>  <h3 class="text-balance ...">受欢迎的曼哈顿汤摊关闭<h3>  <p>纽约人今年冬天面临着更少的温暖...</p></article>

我们还添加了 text-pretty,它尝试使用 text-wrap: pretty 避免段落末尾的孤立词:

受欢迎的曼哈顿汤摊关闭

纽约人今年冬天面临着更少的温暖,因为该市最受尊敬的汤摊意外关闭,导致社区困惑不解。

<article class="text-pretty ...">  <h3>受欢迎的曼哈顿汤摊关闭<h3>  <p>纽约人今年冬天面临着更少的温暖...</p></article>

这些功能的好处在于,即使有人使用旧版浏览器访问您的网站,他们也会回退到常规的换行行为,因此今天开始使用这些功能是完全安全的。


子网格支持

子网格是一个相对较新的 CSS 功能,它使元素可以从其父元素继承网格列或行,从而可以将其子元素放置在父网格中。

HTML
<div class="grid grid-cols-4 gap-4">  <!-- ... -->  <div class="col-span-3 grid grid-cols-subgrid gap-4">    <div class="col-start-2">06</div>  </div>  <!-- ... --></div>

我们在我们正在开发的新 UI 工具包中使用子网格,例如在下拉菜单中,这样如果任何项目有图标,所有其他项目都会缩进以保持文本对齐:

HTML
<div role="menu" class="grid grid-cols-[auto_1fr]">  <a href="#" class="col-span-2 grid-cols-subgrid">    <svg class="mr-2">...</svg>    <span class="col-start-2">账户</span>  </a>  <a href="#" class="col-span-2 grid-cols-subgrid">    <svg class="mr-2">...</svg>    <span class="col-start-2">设置</span>  </a>  <a href="#" class="col-span-2 grid-cols-subgrid">    <span class="col-start-2">退出</span>  </a></div>

当没有项目有图标时,第一列会缩小到 0px,文本会完全对齐到左边。

查看 MDN 上关于子网格的文档以获取完整的入门指南——这是一个一开始很难理解的功能,但一旦掌握,它就是一个改变游戏规则的功能。


扩展的最小宽度、最大宽度和最小高度比例

我们终于扩展了 min-widthmax-widthmin-height 比例,以包含完整的间距比例,因此像 min-w-12 这样的类现在实际上是一个真实的东西:

HTML
<div class="min-w-12">  <!-- ... --></div>

我们应该在 v3.0 中就这样做,但从未真正做到——对不起,不客气。


扩展的不透明度比例

我们还扩展了不透明度比例,以默认包含每 5 步:

HTML
<div class="opacity-35">  <!-- ... --></div>

希望这意味着您的标记中少了一些任意值。 我接下来要找的是 2.5%。


扩展的 grid-rows-* 比例

我们还将内置的网格行数从 6 增加到 12,因为为什么不呢:

HTML
<div class="grid grid-rows-9">  <!-- ... --></div>

也许我们会变得更疯狂,在下一个版本中将其增加到 16。


新的 forced-colors 变体

听说过强制颜色模式吗? 您的网站在其中可能看起来很糟糕。

好吧,现在您至少不能责怪我们了,因为 Tailwind CSS v3.4 包含一个 forced-colors 变体,用于调整强制颜色模式的样式:

HTML
<form>  <input type="checkbox" class="appearance-none forced-colors:appearance-auto ..." /></form>

它对于微调完全自定义的控件非常有用,尤其是与任意值和对 CSS 系统颜色 的工作知识结合使用时。


新的 forced-color-adjust 实用程序

我们还添加了新的 forced-color-adjust-autoforces-color-adjust-none 实用程序,以控制强制颜色模式如何影响您的设计:

HTML
<fieldset>  <legend>选择颜色</legend>  <div class="forced-color-adjust-none ...">    <label>      <input class="sr-only" type="radio" name="color-choice" value="white" />      <span class="sr-only">白色</span>      <span class="size-6 rounded-full bg-white"></span>    </label>    <label>      <input class="sr-only" type="radio" name="color-choice" value="gray" />      <span class="sr-only">灰色</span>      <span class="size-6 rounded-full bg-gray-300"></span>    </label>    <!-- ... -->  </div></fieldset>

这些应该很少使用,但当某些东西必须以特定颜色呈现时,它们会很有用,例如在在线商店中选择某人购买的物品的颜色。

要了解有关所有这些强制颜色的更多信息,我建议阅读 Polypane 博客上的“强制颜色解释:实用指南”——这是我在这个话题上找到的最有用的帖子。


如果您一直在密切关注,您可能会想知道我们在今年夏天的 Tailwind Connect 上预览的 Oxide 引擎改进。

我们最初计划在 v3.4 中进行这些改进,但我们还有一些问题需要解决,这些其他改进已经堆积如山,我们觉得将它们全部发布出去比拖延更有意义。 Oxide 的改进仍在进行中,并将在明年成为下一个 Tailwind CSS 版本的头条改进。

同时,通过使用 npm 更新到最新版本来深入了解 Tailwind CSS v3.4:

$ npm install tailwindcss@latest

有了 :has() 和新的 * 变体,您的 HTML 将比以往任何时候都更加失控。

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