说实话我们并没有真正计划这次发布,但是过去几周我们一直在向 Tailwind 中添加新的激动人心的功能,现在似乎是合适的发布时机了,所以这就是它 — Tailwind CSS v2.2!
这必须是有史以来功能最丰富的 Tailwind 发布版本之一。在 v2.1 中引入 即时(JIT)模式 为我们打开了一扇大门,让我们可以轻松添加许多原本难以实现的酷炫功能,这个版本就充满了很好的例子。
以下是主要亮点:
- 全新的高性能 Tailwind CLI
- Before 和 after 变体
- First-letter/line 变体
- 选中文本变体
- 列表标记变体
- 同级选择器变体
- 完整的伪类支持
- 简化的颜色透明度语法
- 扩展的任意值支持
- 改进的嵌套支持
- 光标颜色工具类
- 背景原点工具类
- 简化的转换和滤镜组合
- 每边框色工具类
- 内置的safelist、transform和extract支持
要查看完整详细信息,请查看 GitHub 上的发布说明。
需要注意的是,虽然这是一个小版本更新,在经典引擎中没有破坏性更改,但是 JIT 模式仍处于预览状态,v2.2 引入了一些可能会影响到你的小改动,所以在升级时请务必阅读发布说明中的 更改和弃用说明。
当你准备好升级时,只需从 npm 安装最新版本即可:
npm install -D tailwindcss@latest全新的高性能 Tailwind CLI
我们从零开始重写了 Tailwind CLI 工具,以性能优先的理念为指导,同时还添加了一系列新功能的支持。
npx tailwindcss -o dist/tailwind.css --watch --jit --purge="./src/**/*.html"以下是一些亮点:
- 无需安装或配置 — 只需在任何地方执行
npx tailwindcss -o output.css即可编译 Tailwind。你甚至可以使用--jit标志启用 JIT 模式,并使用--purge选项传入内容文件,全程无需创建配置文件。 - 监视模式 — 这样你就可以在做出任何更改时自动重建 CSS。
- JIT 性能优化 — 由于我们的 CLI 是专门为 Tailwind 设计的,我们能够进行大量优化,使其成为 JIT 模式下编译 CSS 最快的构建工具。
- 压缩支持 — 现在你可以通过添加
--minify标志使用 cssnano 来压缩你的 CSS。 - PostCSS 插件支持 — 新的 CLI 将读取并遵循你在
postcss.config.js文件中配置的任何额外插件。
它完全向后兼容以前的 CLI,所以如果你已经设置了任何脚本,你应该能够升级到 v2.2 而无需对脚本进行任何更改。
查看我们的 更新的 Tailwind CLI 文档 以了解更多信息。
请注意,如果你使用的是 tailwindcss-cli 包装器包,你可以安全地切换到 tailwindcss,因为我们已经解决了迫使我们创建包装器包的对等依赖问题。
Before 和 after 伪元素变体
此功能仅在 即时模式 下可用。
大家期待多年的功能终于来了!我们添加了对 before 和 after 这样的伪元素的原生支持:
<div class="before:block before:bg-blue-500 after:flex after:bg-pink-300"></div>我们会在你使用 before 或 after 变体时自动设置 content: "" 以确保元素被渲染,但你可以使用新的 content 工具类覆盖它,这些工具类完全支持任意值:
<div class="before:block before:content-['hello'] ..."></div>你甚至可以使用 CSS attr() 函数从属性中获取内容:
<div before="hello world" class="before:block before:content-[attr(before)] ..."></div>当你的内容中有空格时,这会非常有用,因为空格不能用于 CSS 类名。
First-letter/line 变体
此功能仅在 即时模式 下可用。
我们为 first-letter 和 first-line 伪元素添加了变体,所以你可以做一些像首字下沉这样的事情:
<p class="first-letter:float-left first-letter:text-4xl first-letter:font-bold"> The night was March 31, 1996, and it was finally time for Bret Hart to face off against Shawn Michaels in the long anticipated Iron Man match — a 60 minute war of endurance where the man who scored the most number of falls would walk away as the WWF World Heavyweight Champion.</p>选中文本变体
此功能仅在 即时模式 下可用。
我们添加了一个新的 selection 变体,使得样式化高亮文本以匹配你的设计变得非常容易:
<p class="selection:bg-pink-200"> After nearly a grueling hour of warfare with neither man scoring a fall, Hart locked in the Sharpshooter, his signature submission hold. As Michaels screamed in pain, the crowd were certain that Hart was about to walk away from WrestleMania XII as the still-World Heavyweight Champion.</p>我们甚至以一种可以应用于父元素并向下级联的方式构建了这个功能,所以你可以通过将一个工具类应用于 body 来为整个站点设置高亮颜色:
<body class="selection:bg-pink-200"> <!-- ... --> <p> But Michaels didn't give up — he held on until the bell rang and the designated 60 minutes was up. Hart walked away content, thinking that without a clear winner, the title was his to hold. He was not prepared for what would happen next, when Gorilla Monsoon declared the match would continue under sudden death rules. </p></body>列表标记变体
此功能仅在 即时模式 下可用。
你可以使用新的 marker 变体来样式化列表开头的项目符号或数字:
<h1>WrestleMania XII Results</h1><ol class="marker:font-medium marker:text-gray-500"> <li>The British Bulldog, Owen Hart, and Vader defeated Ahmed Johnson, Jake Roberts, and Yokozuna</li> <li>Roddy Piper defeated Goldust</li> <li>Stone Cold Steve Austin defeated Savio Vega</li> <li>The Ultimate Warrior defeated Hunter Hearst Helmsley</li> <li>The Undertaker defeated Diesel</li> <li>Shawn Michaels defeated Bret Hart</li></ol>像 selection 变体一样,我们以一种从父元素级联的方式实现了这个功能,所以你不必为每个列表项重复它。
同级选择器变体
此功能仅在 即时模式 下可用。
Tailwind CSS v2.2 添加了新的 peer-* 变体,其行为类似于 group-* 变体,但用于定位同级元素而不是父元素。
这对于样式化前面的复选框被选中时的元素、浮动标签等非常有用:
<label> <input type="checkbox" class="peer sr-only" /> <span class="h-4 w-4 bg-gray-200 peer-checked:bg-blue-500"> <!-- ... --> </span></label>就像 group 可以与任何其他变体结合一样, peer 也可以,所以你可以随时使用 peer-hover, peer-focus, peer-disabled 等变体。
生成的 CSS 使用 一般同级选择器,如下所示:
.peer:checked ~ .peer-checked\:bg-blue-500 { background-color: #3b82f6;}所以就像在原生 CSS 中一样,它只能用于定位 之前 的同级元素,而不是出现在 DOM 中的后续同级元素。
完整的伪类支持
此功能仅在 即时模式 下可用。
在这个版本中,我们为几乎每一个我们能想到的缺失伪类添加了变体:
only(only-child)first-of-typelast-of-typeonly-of-typetargetdefaultindeterminateplaceholder-shownautofillrequiredvalidinvalidin-rangeout-of-range
个人最喜欢的是 placeholder-shown — 当与新的同级选择器变体结合使用时,它可以实现像浮动标签这样的酷炫效果:
<div class="relative"> <input id="name" class="peer ..." /> <label for="name" class="peer-placeholder-shown:top-4 peer-focus:top-0 ..."> Name </label></div>简化的颜色透明度语法
此功能仅在 即时模式 下可用。
与使用 bg-opacity-50, text-opacity-25 或 placeholder-opacity-40 这样的工具类不同,Tailwind CSS v2.2 为你提供了一种新的颜色透明度简写,你可以直接在颜色工具类中调整颜色的 alpha 通道:
<div class="bg-red-500 bg-opacity-25"><div class="bg-red-500/25"></div>这意味着你现在可以在 Tailwind 的任何地方更改颜色的透明度,即使在我们之前没有特定透明度工具类的地方,例如渐变:
<div class="bg-gradient-to-r from-red-500/50"></div>透明度值取自你的 opacity 规模,但你也可以使用方括号表示法使用任意透明度值:
<div class="bg-red-500/[0.31]"></div>老实说,我对不再需要为你们这些人创建另一个像 placeholderOpacity.js 这样的核心插件感到更兴奋,而不是实际使用这个功能。而且我对这个功能真的很兴奋,所以这说明了一些问题。
扩展的任意值支持
此功能仅在 即时模式 下可用。
我们已经检查了 Tailwind 中的每个核心插件,尽可能添加了最灵活的任意值支持,我认为我们几乎涵盖了所有内容。
你应该能够在几乎任何地方使用你想要的任意值:
<div class="col-start-[73] object-[50%] placeholder-[#aabbcc] ..."></div>如果你发现我们遗漏了一个,请打开一个问题,我们会解决它。
除了使任意值支持更全面之外,我们还添加了一种新的类型提示语法来处理模糊的情况。例如,如果你使用 CSS 变量作为任意值,生成的 CSS 应该是什么并不总是很清楚:
<!-- 这是一个字体大小工具类,还是一个文本颜色工具类? --><div class="text-[var(--mystery-var)]"></div>现在你可以通过在任意值前加上类型名称来向引擎提供提示:
<div class="text-[color:var(--mystery-var)]"></div>目前,支持的类型有:
lengthcoloranglelist
随着人们发现新的边缘情况,我们可能会进一步完善这一点,但这应该会让你走得很远。
改进的嵌套支持
由于 Tailwind 引入了许多非标准的 CSS at-rules,如 @tailwind 和 @apply,当将其与 postcss-nested 或 postcss-nesting 之类的 PostCSS 嵌套插件结合使用时,你经常会遇到奇怪的输出。
为了缓解这个问题,我们在 tailwindcss 包中包含了一个新的 PostCSS 插件,它充当现有嵌套插件和 Tailwind 之间的轻量级兼容层。
所以如果你在项目中需要嵌套支持,请使用我们的插件,并将其放在 PostCSS 插件列表中的 Tailwind 之前:
// postcss.config.jsmodule.exports = { plugins: [ // ... require("tailwindcss/nesting"), require("tailwindcss"), // ... ],};默认情况下,它在内部使用 postcss-nested (因为这是我们在 Tailwind 插件中支持嵌套的方式),但如果你想使用 postcss-nesting,只需将我们的插件作为函数调用并传递 postcss-nesting 插件:
// postcss.config.jsmodule.exports = { plugins: [ // ... require("tailwindcss/nesting")(require("postcss-nesting")), require("tailwindcss"), // ... ],};在内部,这使用了我们引入的新 screen() 函数,你可以使用它从任何配置的断点中获取扩展的媒体表达式:
/* 输入 */@media screen(sm) { /* ... */}/* 输出 */@media (min-width: 640px) { /* ... */}你可能不需要自己使用它,但如果你将 Tailwind 与另一个理解 @media 但不能正确处理 @screen 的工具集成时,它可能会有所帮助。
@screen sm {@media screen(sm) { /* ... */}光标颜色工具类
此功能仅在 即时模式 下可用。
你现在可以使用新的 caret-{color} 工具类设置表单字段中光标的颜色:
<input class="caret-red-500" />这些可以使用 tailwind.config.js 文件中 theme 部分的 caretColor 键进行自定义。
背景原点工具类
我们为 background-origin 属性添加了新的工具类,这些工具类允许你控制元素的背景相对于元素的边框、填充框或内容的位置:
<div class="border-4 border-dashed bg-origin-border p-4 ..." style="background-image: url(...)"> 背景在边框下渲染</div><div class="border-4 border-dashed bg-origin-padding p-4 ..." style="background-image: url(...)"> 背景在边框内渲染,但在任何填充之上</div><div class="border-4 border-dashed bg-origin-content p-4 ..." style="background-image: url(...)"> 背景在任何填充内渲染,并在内容下方</div>在 背景原点文档 中了解更多信息。
简化的转换和滤镜组合
此功能仅在 即时模式 下可用。
transform, filter 和 backdrop-filter 类不再需要 "启用" 各自的一组可组合工具类。
<div class="transform scale-50 filter grayscale backdrop-filter backdrop-blur-sm"><div class="scale-50 grayscale backdrop-blur-sm"></div>现在,只要你使用任何相关的子工具类,这些功能就会自动启用。
重要的是要理解,因为这些工具类不再需要,你不能再期望转换和滤镜默认是 "休眠" 的。如果你依赖于通过切换这些类来有条件地 "激活" 转换或滤镜,你将需要确保你正在切换子工具类本身:
<div class="scale-105 -translate-y-1 hover:transform"><div class="hover:scale-105 hover:-translate-y-1"></div>我不认为这对大多数人来说会是一个真正的问题,但从技术上讲,这是一个破坏性更改,这就是为什么我们将此改进限制在 JIT 引擎中。
每边框色工具类
此功能仅在 即时模式 下可用。
过去四年中每月至少请求一次,我很高兴地分享,我们终于添加了每边框色支持,现在我们不必担心开发样式表的大小。
<div class="border-2 border-t-blue-500 border-r-pink-500 border-b-green-500 border-l-yellow-500"> <!-- ... --></div>去吧,构建丑陋的网站! (开玩笑,开玩笑,我知道它们很有用,冷静下来。)
内置的 safelist、transform 和 extract 支持
我们为许多重要的 PurgeCSS 功能添加了一流的支持,并使它们在 JIT 引擎中也能工作,后者实际上甚至不使用 PurgeCSS。
首先是 safelist, 如果你需要保护特定类不被从生产 CSS 中删除,这非常有用,可能是因为它们用于来自数据库或类似内容的内容:
module.exports = { purge: { content: ["./src/**/*.html"], safelist: [ "bg-blue-500", "text-center", "hover:opacity-100", // ... "lg:text-right", ], }, // ...};请注意,虽然经典引擎在这里接受正则表达式,但 JIT 引擎不会。这是因为当我们按需生成类时,类在使用之前不存在,所以我们没有什么可以匹配表达式的。因此,如果你使用即时模式,请确保你提供完整的类名以获得预期的结果。
接下来是 transform, 它允许你在扫描内容以查找潜在类名之前,为不同的文件扩展名转换内容:
let remark = require("remark");module.exports = { purge: { content: ["./src/**/*.{html,md}"], transform: { md: (content) => { return remark().process(content); }, }, }, // ...};如果你有用一种编译为 HTML 的语言编写的模板,如 Markdown,这非常有用。
最后是 extract, 它允许你自定义 Tailwind 用于检测特定文件类型中的类名的逻辑:
module.exports = { purge: { content: ["./src/**/*.{html,md}"], extract: { pug: (content) => { return /[^<>"'`\s]*/.match(content); }, }, }, // ...};这是一个高级功能,大多数用户不需要它。Tailwind 中的默认提取逻辑对于几乎所有项目都非常有效。
有关这些功能的更多信息,请查看我们的 优化生产文档。
升级
要升级到 Tailwind CSS v2.2,请从 npm 安装最新版本:
npm install -D tailwindcss@latest如果你正在使用即时模式预览,你还需要阅读发布说明中的 更改和弃用说明。
准备好升级了吗? 从 npm 获取 →