Tailwind CSS v3.4:动态视口单位、:has() 支持、平衡标题、子网格等等

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 旨在适应消失的浏览器 Chrome,Tailwind CSS v3.4 开箱即用地支持它们

在视口中上下滚动以隐藏/显示浏览器 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>

在过去几个月里,我一直在构建新的 UI 工具包,感觉每周都能为 :has() 找到新的用例,它已经取代了我们代码中大量的 JavaScript。

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

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

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


使用 * 变体样式化子元素

这是一个人们一直以来都想要的 —— 一种使用实用程序类从父元素样式化子元素的方法。

我们添加了一个新的 * 变体,它针对直接子元素,让你能够执行这样的操作

分类

销售
营销
SEO
分析
设计
策略
安全
增长
移动
UX/UI
<div>
<h2>Categories:<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>Sales</li>
<li>Marketing</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>First name</Label>
<Input />
<Description>Please tell me you know your own name.</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>

我们一直都想添加这个功能,但总是纠结于确切的名称 —— 与 w-*h-* 相比,size-* 感觉输入量太大,而 s-* 又感觉太神秘了。

但在使用了几周后,我可以果断地说,即使名称较长,它也比单独的宽度和高度实用程序要好得多。超级方便,特别是当你将其与变体组合或使用复杂的任意值时。


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

你花了多少时间摆弄 max-width 或插入响应式换行符,试图让那些小节标题在你的着陆页上很好地换行?现在你可以零时间投入了,因为浏览器可以使用 text-wrap: balance 为你完成。

备受欢迎的曼哈顿汤摊关门

纽约人今年冬天面临着较少的温暖,因为这座城市最受尊敬的汤摊意外关闭,此前发生了一系列令社区感到困惑的事件。

<article>
<h3 class="text-balance ...">Beloved Manhattan soup stand closes<h3>
<p>New Yorkers are facing the winter chill...</p>
</article>

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

备受欢迎的曼哈顿汤摊关门

纽约人今年冬天面临着较少的温暖,因为这座城市最受尊敬的汤摊意外关闭,此前发生了一系列令社区感到困惑的事件。

<article class="text-pretty ...">
<h3>Beloved Manhattan soup stand closes<h3>
<p>New Yorkers are facing the winter chill...</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">Account</span>
</a>
<a href="#" class="col-span-2 grid-cols-subgrid">
<svg class="mr-2">...</svg>
<span class="col-start-2">Settings</span>
</a>
<a href="#" class="col-span-2 grid-cols-subgrid">
<span class="col-start-2">Sign out</span>
</a>
</div>

当所有项目都没有图标时,第一列会缩小到 0px,文本会一直向左对齐。

查看 MDN 上关于子网格的文档以获得完整的入门知识 —— 这是一个有点棘手的功能,一开始可能难以理解,但一旦你理解了,它就会改变游戏规则。


扩展的 min-width、max-width 和 min-height 比例

我们终于扩展了 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>Choose a color</legend>
<div class="forced-color-adjust-none ...">
<label>
<input class="sr-only" type="radio" name="color-choice" value="white" />
<span class="sr-only">White</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">Gray</span>
<span class="size-6 rounded-full bg-gray-300"></span>
</label>
<!-- ... -->
</div>
</fieldset>

这些应该非常谨慎地使用,但当必须以特定颜色渲染某些东西时,它们可能很有用,例如在网上商店中选择某人正在购买的东西的颜色。

要了解有关所有这些强制颜色内容的更多信息,我建议阅读 Polypane 博客上的《强制颜色详解:实用指南》—— 到目前为止,这是我找到的关于此主题最有用的文章。


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

我们最初计划在 v3.4 中推出这些改进,但我们还有一些事情需要解决,并且其他许多改进也一直在积累,因此我们认为最好将所有内容都发布出去,而不是将其保留下来。Oxide 的内容仍在开发中,并将成为新年下一个 Tailwind CSS 版本的头条改进。

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

$ npm install tailwindcss@latest

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

将我们的所有更新直接发送到你的 收件箱。
注册我们的新闻通讯。

版权所有 © 2025 Tailwind Labs Inc.·商标政策