我不能说我们真的打算这样做,但在过去的几周里,我们一直很高兴地将许多新鲜有趣的功能放入 Tailwind,现在感觉是时候发布一个版本了,所以在这里——Tailwind CSS v2.2!
这是有史以来功能最丰富的 Tailwind 发布之一。 在 v2.1 中引入的 Just-in-Time 模式 为我们提供了许多酷炫功能的可能性,我们无法轻松添加的,这次发布充满了这些优秀示例。
以下是亮点:
- 全新高性能 Tailwind CLI
- 前后变体
- 首字母/首行变体
- 选定文本变体
- 列表标记变体
- 兄弟选择器变体
- 详尽的伪类支持
- 简写颜色不透明度语法
- 扩展任意值支持
- 改进的嵌套支持
- 光标颜色工具
- 背景起源工具
- 简化的变换和过滤器组合
- 每边边框颜色工具
- 内置安全列表、转换和提取支持
有关完整详细信息,请查看 GitHub 上的发布说明。
值得注意的是,虽然这是一个小版本,并且经典引擎中没有破坏性更改,Just-in-Time 模式仍处于预览状态,而 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
,因为我们已经解决了迫使我们首次创建包装器包的对等依赖问题。
前后伪元素变体
此功能仅在 Just-in-Time 模式 中可用。
人们已经请求这个功能很多年了,现在终于来了!我们为伪元素如 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 类名。
首字母/首行变体
此功能仅在 Just-in-Time 模式 中可用。
我们为 first-letter
和 first-line
伪元素添加了变体,因此您可以做到像掉落首字母这样的效果:
<p class="first-letter:float-left first-letter:text-4xl first-letter:font-bold"> 那个夜晚是1996年3月31日,布雷特·哈特终于要与肖恩·迈克尔在期待已久的铁人赛中角逐——一场60分钟的耐力战,得分最多的人将作为 WWF 世界重量级冠军离开。</p>
选定文本变体
此功能仅在 Just-in-Time 模式 中可用。
我们添加了一个新的 selection
变体,使其非常容易样式高亮文本以匹配您的设计:
<p class="selection:bg-pink-200"> 在经过近一个小时的战争而没有任何人得分后,哈特锁住了 Sharpshooter,他的标志性降服技。随着迈克尔斯在痛苦中尖叫,人群确信哈特将继续成为摔角大会 XII 的世界重量级冠军。</p>
我们甚至构建了这个功能,可以将其应用于父元素并向下级联,因此您可以通过将工具应用于主体来为整个网站设置高亮颜色:
<body class="selection:bg-pink-200"> <!-- ... --> <p> 但迈克尔斯并没有放弃——他坚持到铃声响起,规定的60分钟结束了。哈特认为没有明确的获胜者,冠军的头衔是他的。他没有准备好接下来的情况,戈里拉·蒙新闻宣称比赛将在突然死亡法则下继续进行。 </p></body>
列表标记变体
此功能仅在 Just-in-Time 模式 中可用。
您可以使用新的 marker
变体来样式列表开头的项目符号或数字:
<h1>摔角大会 XII 结果</h1><ol class="marker:font-medium marker:text-gray-500"> <li>英国斗犬、欧文·哈特和维达击败阿赫德·约翰逊、杰克·罗伯茨和横滨</li> <li>罗迪·派珀击败金尘</li> <li>石冷史蒂夫·奥斯汀击败萨维奥·维加</li> <li>终极战士击败亨特·赫斯特·海尔姆斯利</li> <li>坟墓人击败柴油</li> <li>肖恩·迈克尔斯击败布雷特·哈特</li></ol>
与 selection
变体一样,我们以一种方式实现了它,可以从父级向下级联,因此您不必为每个列表项重复它。
兄弟选择器变体
此功能仅在 Just-in-Time 模式 中可用。
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 后面的兄弟。
详尽的伪类支持
此功能仅在 Just-in-Time 模式 中可用。
我们为几乎所有缺少的伪类添加了变体:
only
(only-child)first-of-type
last-of-type
only-of-type
target
default
indeterminate
placeholder-shown
autofill
required
valid
invalid
in-range
out-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 ..."> 名字 </label></div>
简写颜色不透明度语法
此功能仅在 Just-in-Time 模式 中可用。
与其使用像 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
这样的核心插件,而不是真正使用这个功能。我对这个功能真的很兴奋,所以这说明了许多问题。
扩展任意值支持
此功能仅在 Just-in-Time 模式 中可用。
我们检查了 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>
当前,支持的类型包括:
length
color
angle
list
随着人们对新边缘情况的发现,我们可能会逐步充实这个列表,但这应该能让您走得很远。
改进的嵌套支持
由于 Tailwind 引入了许多非标准的 CSS at-rule,例如 @tailwind
和 @apply
,因此将其与像 postcss-nested
或 postcss-nesting
这样的 PostCSS 嵌套插件相结合时,您可能会遇到奇怪的输出。
为了解决这个问题,我们在 tailwindcss
包中包含了一种新的 PostCSS 插件,作为现有嵌套插件与 Tailwind 之间的轻量兼容层。
因此,如果您在项目中需要嵌套支持,请使用我们的插件,并将其置于 Tailwind 之前的 PostCSS 插件列表中:
// 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) { /* ... */}
光标颜色工具
此功能仅在 Just-in-Time 模式 中可用。
您现在可以使用新的 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>
在 背景起源文档 中了解更多信息。
简化的变换和过滤器组合
此功能仅在 Just-in-Time 模式 中可用。
现在不再需要使用 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 引擎。
每边边框颜色工具
此功能仅在 Just-in-Time 模式 中可用。
在过去四年中每月至少请求一次,我很高兴地分享,由于我们不必担心开发样式表的大小,我们终于添加了每边边框颜色支持。
<div class="border-2 border-t-blue-500 border-r-pink-500 border-b-green-500 border-l-yellow-500"> <!-- ... --></div>
去吧,建造丑陋的网站吧! (开玩笑,开玩笑,我知道它们非常实用,冷静点。)
内置安全列表、转换和提取支持
我们为许多重要的 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
如果您使用的是 Just-in-Time 模式预览,您还需要阅读发布说明中的 更改和弃用。
准备好升级了吗? 从 npm 获取它 →