Tailwind CSS v3.1:你想疯狂一把吗?来吧,让我们疯狂起来!
- 日期
- Adam Wathan
自从我们发布 Tailwind CSS v3.0 已经过去了大约六个月,尽管我们一直在代码库中收集许多小的改进,但我们还没有找到那个功能,它会让你说“好吧,现在是发布的时候了”。
然后,几周前的一个随机的星期六晚上,我在我们的 Discord 上和 Robin 讨论如何使用:has
和文档中更深层的类来定位html
元素,并解释了如果我们添加对任意变体的支持,我认为它会是什么样子——这是我一年多来一直想解决的问题。
20 分钟后,Robin 就有了可行的概念证明(只有六行代码!),在 Jordan 在我们的类检测引擎中进行了一个多小时的正则表达式奇迹之后,任意变体 就诞生了,我们有了值得发布的功能。
所以,它来了——Tailwind CSS v3.1!有关所有修复和改进的完整列表,请查看 发布说明,但以下是重点。
- 第一方 TypeScript 类型
- CLI 中内置支持 CSS 导入
- 使用主题函数更改颜色不透明度
- 更轻松的 CSS 变量颜色配置
- 边框间距实用程序
- 启用和可选变体
- 首选对比度变体
- 为原生对话框背景样式
- 任意值,但用于变体
从 npm 安装最新版本的tailwindcss
来升级您的项目。
npm install tailwindcss@latest
或者启动一个 Tailwind Play,在浏览器中玩弄所有新功能。
第一方 TypeScript 类型
我们现在为所有在使用 Tailwind 时使用的 JS API 提供类型,最值得注意的是 `tailwind.config.js` 文件。这意味着您将获得各种有用的 IDE 支持,并且更容易对配置进行更改,而无需过多地参考文档。
要设置它,只需在您的配置定义上方添加类型注释
/** @type {import('tailwindcss').Config} */
module.exports = {
content: [
// ...
],
theme: {
extend: {},
},
plugins: [],
}
如果您是 TypeScript 狂热爱好者,您可能会喜欢浏览实际的 类型定义 - 那里有很多有趣的东西来支持这样一个潜在的复杂对象。
CLI 中对 CSS 导入的内置支持
如果您使用我们的 CLI 工具来编译您的 CSS,postcss-import
现在已内置,因此您可以将自定义 CSS 组织到多个文件中,而无需任何额外的配置。
@import "tailwindcss/base";
@import "./select2-theme.css";
@import "tailwindcss/components";
@import "tailwindcss/utilities";
如果您没有使用我们的 CLI 工具,而是将 Tailwind 作为 PostCSS 插件使用,您仍然需要像使用 `autoprefixer` 一样自己安装和配置 `postcss-import`,但是如果您使用的是我们的 CLI 工具,这将完全正常工作。
如果您使用的是我们的 独立 CLI 并且根本不想安装任何节点依赖项,这将特别方便。
使用主题函数更改颜色不透明度
我认为很多人不知道这一点,但 Tailwind 向您的 CSS 文件公开了一个 theme()
函数,它允许您从您的配置文件中获取值 - 将它们变成可以重复使用的变量。
.select2-dropdown {
border-radius: theme(borderRadius.lg);
background-color: theme(colors.gray.100);
color: theme(colors.gray.900);
}
/* ... */
但是,一个限制是您无法调整以这种方式获取的任何颜色的 alpha 通道。因此,在 v3.1 中,我们添加了对使用斜杠语法调整不透明度的支持,就像您使用现代 `rgb` 和 `hsl` CSS 颜色函数一样。
.select2-dropdown {
border-radius: theme(borderRadius.lg);
background-color: theme(colors.gray.100 / 50%);
color: theme(colors.gray.900);
}
/* ... */
我们也让它在您的 `tailwind.config.js` 文件中的 `theme` 函数中起作用。
module.exports = {
content: [
// ...
],
theme: {
extend: {
colors: ({ theme }) => ({
primary: theme('colors.blue.500'),
'primary-fade': theme('colors.blue.500 / 75%'),
})
},
},
plugins: [],
}
您甚至可以在任意值中使用这些东西,这非常疯狂 - 老实说,对于奇怪的自定义渐变等非常有用。
<div class="bg-[image:linear-gradient(to_right,theme(colors.red.500)_75%,theme(colors.red.500/25%))]">
<!-- ... -->
</div>
任何可以避免编辑 CSS 文件的东西,对吧?
更轻松的 CSS 变量颜色配置
如果你喜欢将颜色定义和配置为 CSS 变量,你可能现在在你的 tailwind.config.js
文件中有一些可怕的样板代码
function withOpacityValue(variable) {
return ({ opacityValue }) => {
if (opacityValue === undefined) {
return `rgb(var(${variable}))`
}
return `rgb(var(${variable}) / ${opacityValue})`
}
}
module.exports = {
theme: {
colors: {
primary: withOpacityValue('--color-primary'),
secondary: withOpacityValue('--color-secondary'),
// ...
}
}
}
我们在 v3.1 中通过添加对使用格式字符串定义颜色的支持,使这变得不那么糟糕,而不是必须使用函数
module.exports = {
theme: {
colors: {
primary: 'rgb(var(--color-primary) / <alpha-value>)',
secondary: 'rgb(var(--color-secondary) / <alpha-value>)',
// ...
}
}
}
你不再需要编写接收 opacityValue
参数的函数,你只需编写一个包含 <alpha-value>
占位符的字符串,Tailwind 将根据实用程序用正确的 alpha 值替换该占位符。
如果你以前从未见过这些,请查看我们更新的 使用 CSS 变量 文档以了解更多详细信息。
边框间距实用程序
我们添加了一组新的 border-spacing
属性实用程序,因此你可以使用 独立边框 时控制表格边框之间的间距
州 | 城市 |
---|---|
印第安纳州 | 印第安纳波利斯 |
俄亥俄州 | 哥伦布 |
密歇根州 | 底特律 |
<table class="border-separate border-spacing-2 ..."> <thead> <tr> <th class="border border-slate-300 ...">State</th> <th class="border border-slate-300 ...">City</th> </tr> </thead> <tbody> <tr> <td class="border border-slate-300 ...">Indiana</td> <td class="border border-slate-300 ...">Indianapolis</td> </tr> <!-- ... --> </tbody> </table>
<table class="border-separate border-spacing-2 ..."> <thead> <tr> <th class="border border-slate-600 ...">State</th> <th class="border border-slate-600 ...">City</th> </tr> </thead> <tbody> <tr> <td class="border border-slate-700 ...">Indiana</td> <td class="border border-slate-700 ...">Indianapolis</td> </tr> <!-- ... --> </tbody> </table>
我知道你在想什么——“我一生中从未想过要构建一个看起来像这样的表格……”——但请听我说一下!
这实际上非常有用的一种情况是,当构建一个带有粘性标题行的表格时,你想要在标题下方有一个持久的下边框
滚动此表格以查看粘性标题行的实际效果
姓名 | 角色 |
---|---|
Courtney Henry | 管理员 |
汤姆·库克 | 成员 |
惠特尼·弗朗西斯 | 管理员 |
莱昂纳德·克拉斯纳 | 所有者 |
弗洛伊德·迈尔斯 | 成员 |
艾米丽·塞尔曼 | 成员 |
克里斯汀·沃森 | 管理员 |
艾玛·多西 | 成员 |
艾丽西亚·贝尔 | 管理员 |
珍妮·威尔逊 | 所有者 |
安娜·罗伯茨 | 成员 |
本杰明·拉塞尔 | 成员 |
杰弗里·韦伯 | 管理员 |
凯瑟琳·墨菲 | 成员 |
<table class="border-separate border-spacing-0">
<thead class="bg-gray-50">
<tr>
<th class="sticky top-0 z-10 border-b border-gray-300 ...">Name</th>
<th class="sticky top-0 z-10 border-b border-gray-300 ...">Email</th>
<th class="sticky top-0 z-10 border-b border-gray-300 ...">Role</th>
</tr>
</thead>
<tbody class="bg-white">
<tr>
<td class="border-b border-gray-200 ...">Courtney Henry</td>
<td class="border-b border-gray-200 ...">[email protected]</td>
<td class="border-b border-gray-200 ...">Admin</td>
</tr>
<!-- ... -->
</tbody>
</table>
你可能会认为你可以直接使用 border-collapse
,因为你实际上不需要边框之间有任何间距,但你错了。如果没有 border-separate
和 border-spacing-0
,边框会滚动而不是粘在标题下方。CSS 真有趣,不是吗?
查看 边框间距文档 以了解更多详细信息。
启用和可选变体
我们为 :enabled
和 :optional
伪类添加了新的变体,它们在表单元素处于启用和可选状态时会针对这些元素。
“但是亚当,我为什么要使用这些,启用和可选甚至不是状态,它们是默认值。你甚至会制作网站吗?”
哎哟,这很痛,因为这是真的——我现在几乎只写邮件,并在 GitHub 上一遍又一遍地回答同样的问题。
但是看看这个禁用的按钮示例
<button type="button" class="bg-indigo-500 hover:bg-indigo-400 disabled:opacity-75 ..." disabled>
Processing...
</button>
注意,当您将鼠标悬停在按钮上时,即使它被禁用,背景颜色仍然会发生变化?在此版本之前,您通常会像这样修复它
<button type="button" class="disabled:hover:bg-indigo-500 bg-indigo-500 hover:bg-indigo-400 disabled:opacity-75 ..." disabled>
Processing...
</button>
但是使用新的 enabled
修饰符,您可以改为这样写
<button type="button" class="bg-indigo-500 hover:enabled:bg-indigo-400 disabled:opacity-75 ..." disabled>
Processing...
</button>
我们没有在按钮被禁用时将悬停颜色覆盖回默认颜色,而是将 hover
和 enabled
变体组合在一起,以便在按钮被禁用时根本不应用悬停样式。我认为这样更好!
这是一个将新的optional
修饰符与我们的兄弟状态功能结合在一起的示例,用于隐藏非必填字段的“必填”提示
<form>
<div>
<label for="email" ...>Email</label>
<div>
<input required class="peer ..." id="email" />
<div class="peer-optional:hidden ...">
Required
</div>
</div>
</div>
<div>
<label for="name" ...>Name</label>
<div>
<input class="peer ..." id="name" />
<div class="peer-optional:hidden ...">
Required
</div>
</div>
</div>
<!-- ... -->
</form>
这样你就可以对所有表单组使用相同的标记,并让 CSS 处理所有条件渲染,而不是自己处理。很酷吧!
偏好对比度变体
你知道有一个prefers-contrast
媒体查询吗?确实有,而且现在 Tailwind 默认支持它。
使用新的contrast-more
和contrast-less
变体,当用户请求更多或更少的对比度时修改你的设计,通常通过操作系统辅助功能偏好设置,例如 macOS 上的“增加对比度”。
尝试在你的开发者工具中模拟prefers-contrast: more
,看看变化。
<form>
<label class="block">
<span class="block text-sm font-medium text-slate-700">Social Security Number</span>
<input class="border-slate-200 placeholder-slate-400 contrast-more:border-slate-400 contrast-more:placeholder-slate-500"/>
<p class="mt-2 opacity-10 contrast-more:opacity-100 text-slate-600 text-sm">
We need this to steal your identity.
</p>
</label>
</form>
我写了一些文档,但说实话,我在这里写的比那里写的更多。
样式原生对话框背景
有一个非常新的HTML <dialog>
元素,具有令人惊讶的不错的浏览器支持,如果你喜欢走在技术前沿,值得尝试一下。
对话框有一个新的::backdrop
伪元素,它在对话框打开时呈现,而 Tailwind CSS v3.1 添加了一个新的backdrop
修饰符,你可以用它来设置这个元素的样式。
<dialog class="backdrop:bg-slate-900/50 ...">
<form method="dialog">
<!-- ... -->
<button value="cancel">Cancel</button>
<button>Submit</button>
</form>
</dialog>
如果您想更深入地了解这个功能,我建议您阅读 MDN 对话框文档 — 这非常令人兴奋,但需要学习很多东西。
任意值,但用于变体
好的,这个对我来说是真正的亮点 — 您知道我们如何为您提供 addVariant
API 来创建您自己的自定义变体吗?
const plugin = require('tailwindcss/plugin')
module.exports = {
// ...
plugins: [
plugin(function({ addVariant }) {
addVariant('third', '&:nth-child(3)')
})
]
}
…并且您知道我们如何使用 任意值 在您的 HTML 中直接使用任何您想要的实用程序值吗?
<div class="top-[117px]">
<!-- ... -->
</div>
Tailwind CSS v3.1 引入了 任意变体,让您直接在 HTML 中创建自己的临时变体
<div class="[&:nth-child(3)]:py-0">
<!-- ... -->
</div>
这对于感觉需要参数化的变体非常有用,例如,如果浏览器支持使用 @supports
查询的特定 CSS 功能,则添加样式
<div class="bg-white [@supports(backdrop-filter:blur(0))]:bg-white/50 [@supports(backdrop-filter:blur(0))]:backdrop-blur">
<!-- ... -->
</div>
您甚至可以使用此功能使用任意变体(如 [&>*]
)来定位子元素
-
Kristen Ramos
-
弗洛伊德·迈尔斯
-
Courtney Henry
<ul role="list" class="[&>*]:p-4 [&>*]:bg-white [&>*]:rounded-lg [&>*]:shadow space-y-4">
<li class="flex">
<img class="h-10 w-10 rounded-full" src="..." alt="" />
<div class="ml-3 overflow-hidden">
<p class="text-sm font-medium text-slate-900">Kristen Ramos</p>
<p class="text-sm text-slate-500 truncate">[email protected]</p>
</div>
</li>
<!-- ... -->
</ul>
您甚至可以为第二个子 li
中的第一个 p
设置样式,但仅在 hover
状态下
尝试将鼠标悬停在“Floyd Miles”文本上
-
Kristen Ramos
-
弗洛伊德·迈尔斯
-
Courtney Henry
<ul role="list" class="hover:[&>li:nth-child(2)>div>p:first-child]:text-indigo-500 [&>*]:p-4 [&>*]:bg-white [&>*]:rounded-lg [&>*]:shadow space-y-4">
<!-- ... -->
<li class="flex">
<img class="h-10 w-10 rounded-full" src="..." alt="" />
<div class="ml-3 overflow-hidden">
<p class="text-sm font-medium text-slate-900">Floyd Miles</p>
<p class="text-sm text-slate-500 truncate">[email protected]</p>
</div>
</li>
<!-- ... -->
</ul>
现在,您应该这样做吗?可能不太经常,但老实说,当您尝试为无法直接更改的 HTML 设置样式时,它可能是一个非常有用的逃生舱口。它是一把锋利的刀,但最好的厨师不会用安全剪刀准备食物。
玩一玩它们,我敢打赌您会发现它们在需要时是一个很棒的工具。我们正在我们正在开发的一些新网站模板中使用它们,并且体验比创建自定义类要好得多。
这就是 Tailwind CSS v3.1!它只是一个次要版本更改,因此没有重大更改,您应该可以通过安装最新版本来更新您的项目
npm install tailwindcss@latest
有关所有更改的完整列表,包括错误修复和一些未在此处提及的小改进,请查看 GitHub 上的 发布说明。
我已经为 Tailwind CSS v3.2 想好了很多想法(也许最终会有文字阴影?!),但现在我们正在努力推出这些新的 网站模板。在一两周内,我们将发布有关该主题的更多更新!