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 被设计成适应那些消失的浏览器界面,而 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>类别:<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 博客上的文章——这是我找到的关于这个主题最有用的文章。


如果你一直在密切关注,你可能会想起 Oxide,我们在这个夏天的 Tailwind Connect 预览的引擎改进。

我们最初将这些改进安排在 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.