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

日期
Tailwind CSS v3.3

没有什么比构建 一个全新的产品 更能让你找到自己工具中所有你希望拥有的功能,因此我们利用了其中的一些灵感,将其转化为 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]:ring-indigo-500 has-[:checked]:text-indigo-900 has-[:checked]:bg-indigo-50 ..">
  <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>

我们一直想添加这个功能,但一直纠结于确切的名称——size-* 感觉比 w-*h-* 输入太多,而 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="grid grid-cols-subgrid gap-4 col-span-3">
      <div class="col-start-2">06</div>
  </div>
  <!-- ... -->
</div>

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

HTML
<div role="menu" class="grid grid-cols-[auto_1fr]">
  <a href="#" class="grid-cols-subgrid col-span-2">
    <svg class="mr-2">...</svg>
    <span class="col-start-2">Account</span>
  </a>
  <a href="#" class="grid-cols-subgrid col-span-2">
    <svg class="mr-2">...</svg>
    <span class="col-start-2">Settings</span>
  </a>
  <a href="#" class="grid-cols-subgrid col-span-2">
    <span class="col-start-2">Sign out</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>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 将比以往任何时候都更加不受控制。