插件
使用可重复使用的第三方插件扩展 Tailwind。
概览
插件允许您使用 JavaScript 注册新的样式,以便将其注入用户样式表中,而不是使用 CSS。
要开始使用您的第一个插件,请从 tailwindcss/plugin 中导入 Tailwind 的 plugin 函数。然后在您的 plugins 数组内,使用匿名函数作为第一个参数调用导入的 plugin 函数。
const plugin = require('tailwindcss/plugin')
module.exports = {
plugins: [
plugin(function({ addUtilities, addComponents, e, config }) {
// Add your custom styles here
}),
]
}插件函数接收一个对象参数,可以解构为几个辅助函数:
addUtilities(),用于注册新的静态实用样式matchUtilities(),用于注册新的动态实用样式addComponents(),用于注册新的静态组件样式matchComponents(),用于注册新的动态组件样式addBase(),用于注册新的基本样式addVariant(),用于注册自定义静态变体matchVariant(),用于注册自定义动态变体theme(),用于查找用户主题配置中的值config(),用于查找用户的 Tailwind 配置中的值corePlugins(),用于检查核心插件是否已启用e(),用于手动转义用于类名的字符串
官方插件
我们已经为一些流行功能开发了一些官方插件,由于某种原因,这些功能目前还不适合放在核心中。
插件可以通过 npm 安装到您的项目中,然后将它们添加到您的 tailwind.config.js 文件中。
/** @type {import('tailwindcss').Config} */
module.exports = {
// ...
plugins: [
require('@tailwindcss/typography'),
require('@tailwindcss/forms'),
require('@tailwindcss/aspect-ratio'),
require('@tailwindcss/container-queries'),
]
}排版设计
@tailwindcss/typography 插件添加了一组 prose 类,可以快速地为来自 Markdown 或 CMS 数据库等来源的内容块添加合理的排版样式。
<article class="prose lg:prose-xl">
<h1>Garlic bread with cheese: What the science tells us</h1>
<p>
For years parents have espoused the health benefits of eating garlic bread with cheese to their
children, with the food earning such an iconic status in our culture that kids will often dress
up as warm, cheesy loaf for Halloween.
</p>
<p>
But a recent study shows that the celebrated appetizer may be linked to a series of rabies cases
springing up around the country.
</p>
<!-- ... -->
</article>表单
@tailwindcss/forms 插件添加了一个主观的表单重置层,使得使用实用类更容易地为表单元素添加样式。
<!-- 实际上,您可以自定义选择元素上的填充: -->
<select class="px-4 py-3 rounded-full">
<!-- ... -->
</select>
<!-- 或者使用文本颜色工具更改复选框颜色: -->
<input type="checkbox" class="rounded text-pink-500" />宽高比
@tailwindcss/aspect-ratio 插件是对原生 aspect-ratio 支持的替代方案,适用于旧版浏览器,并添加了 aspect-w-{n} 和 aspect-h-{n} 类,可以组合在一起为元素提供固定的宽高比。
<div class="aspect-w-16 aspect-h-9">
<iframe src="https://www.youtube.com/embed/dQw4w9WgXcQ" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>
</div>容器查询
@tailwindcss/container-queries 插件添加了新的 @{size} 变体,如 @sm 和 @md ,让您可以根据标记为 @container 的父元素的尺寸而不是视口来设置元素的样式。
<div class="@container">
<div class="@lg:text-sky-400">
<!-- ... -->
</div>
</div>添加实用工具
addUtilities 和 matchUtilities 函数允许您在 Tailwind 的 utilities 层中注册新样式。
与默认情况下包含在 Tailwind 中的实用工具一样,插件添加的实用工具只有在项目中实际被使用时才会包含在生成的 CSS 中。
静态实用程序
使用 addUtilities 函数注册不支持用户提供的值的简单静态实用程序:
const plugin = require('tailwindcss/plugin')
module.exports = {
plugins: [
plugin(function({ addUtilities }) {
addUtilities({
'.content-auto': {
'content-visibility': 'auto',
},
'.content-hidden': {
'content-visibility': 'hidden',
},
'.content-visible': {
'content-visibility': 'visible',
},
})
})
]
}了解如何在 CSS-in-JS 语法参考中以 JavaScript 表示样式的更多信息。
动态实用工具
使用 matchUtilities 函数注册实用工具,这些实用工具映射到用户 theme 配置中定义的值:
const plugin = require('tailwindcss/plugin')
module.exports = {
theme: {
tabSize: {
1: '1',
2: '2',
4: '4',
8: '8',
}
},
plugins: [
plugin(function({ matchUtilities, theme }) {
matchUtilities(
{
tab: (value) => ({
tabSize: value
}),
},
{ values: theme('tabSize') }
)
})
]
}以这种方式定义的实用程序还支持任意值,这意味着您可以使用方括号表示法使用主题中不存在的值:
<div class="tab-[13]">
<!-- ... -->
</div>前缀和 important
默认情况下,插件实用程序会自动遵守用户的 prefix 和 important 偏好。
这意味着根据这个 Tailwind 配置:
/** @type {import('tailwindcss').Config} */
module.exports = {
prefix: 'tw-',
important: true,
// ...
}…上面的示例插件将生成以下 CSS:
.tw-content-auto {
content-visibility: auto !important;
}
.tw-content-hidden {
content-visibility: hidden !important;
}
.tw-content-visible {
content-visibility: visible !important;
}与修饰符一起使用
使用 addUtilities 添加的任何自定义实用程序都可以自动与修饰符一起使用:
<div class="content-auto lg:content-visible">
<!-- ... -->
</div>在悬停、焦点和其他状态文档中了解更多信息。
提供默认值
实用插件可以通过将配置对象作为 plugin 函数的第二个参数来提供默认值:
const plugin = require('tailwindcss/plugin')
module.exports = plugin(function({ matchUtilities, theme }) {
matchUtilities(
{
tab: (value) => ({
tabSize: value
}),
},
{ values: theme('tabSize') }
)
}, {
theme: {
tabSize: {
1: '1',
2: '2',
4: '4',
8: '8',
}
}
})这些值的行为方式与默认配置中的值相同,并且可以被最终用户覆盖或扩展。
添加组件
addComponents 函数允许您在 Tailwind 的 components 层中注册新样式。
使用它来添加更具主观性、复杂的类,如按钮、表单控件、警报等;这些是您经常在其他框架中看到的预构建组件,您可能需要使用实用程序类来覆盖。
要从插件中添加新的组件样式,请调用 addComponents ,并使用 CSS-in-JS 语法传入您的样式:
const plugin = require('tailwindcss/plugin')
module.exports = {
plugins: [
plugin(function({ addComponents }) {
addComponents({
'.btn': {
padding: '.5rem 1rem',
borderRadius: '.25rem',
fontWeight: '600',
},
'.btn-blue': {
backgroundColor: '#3490dc',
color: '#fff',
'&:hover': {
backgroundColor: '#2779bd'
},
},
'.btn-red': {
backgroundColor: '#e3342f',
color: '#fff',
'&:hover': {
backgroundColor: '#cc1f1a'
},
},
})
})
]
}与 Tailwind 中的其他组件类一样,插件添加的组件类只有在项目中实际使用时才会包含在生成的 CSS 中。
前缀和 important
默认情况下,组件类自动遵守用户的 prefix 偏好,但不受用户的 important 偏好影响。
这意味着,给定这个 Tailwind 配置:
/** @type {import('tailwindcss').Config} */
module.exports = {
prefix: 'tw-',
important: true,
// ...
}…上面的示例插件将生成以下 CSS:
.tw-btn {
padding: .5rem 1rem;
border-radius: .25rem;
font-weight: 600;
}
.tw-btn-blue {
background-color: #3490dc;
color: #fff;
}
.tw-btn-blue:hover {
background-color: #2779bd;
}
.tw-btn-red {
background-color: #e3342f;
color: #fff;
}
.tw-btn-red:hover {
background-color: #cc1f1a;
}虽然很少有理由使组件声明重要,但如果你真的需要这样做,你总是可以手动添加 !important :
const plugin = require('tailwindcss/plugin')
module.exports = {
plugins: [
plugin(function({ addComponents }) {
addComponents({
'.btn': {
padding: '.5rem 1rem !important',
borderRadius: '.25rem !important',
fontWeight: '600 !important',
},
// ...
})
})
]
}选择器中的所有类将默认添加前缀,因此,如果您添加了更复杂的样式,例如:
const plugin = require('tailwindcss/plugin')
module.exports = {
prefix: 'tw-',
plugins: [
plugin(function({ addComponents }) {
const components = {
// ...
'.navbar-inverse a.nav-link': {
color: '#fff',
}
}
addComponents(components)
})
]
}…将生成以下 CSS:
.tw-navbar-inverse a.tw-nav-link {
color: #fff;
}与修饰符一起使用
使用 addComponents 添加的任何组件类都可以自动与修饰符一起使用:
<div class="btn md:btn-lg">
<!-- ... -->
</div>在悬停、焦点和其他状态文档中了解更多信息。
添加基本样式
addBase 函数允许您在 Tailwind 的 base 层中注册新样式。使用它来添加诸如基本排版样式、有主见的全局重置或 @font-face 规则等内容。
要从插件中添加新的基本样式,请调用 addBase ,并使用 CSS-in-JS 语法传入您的样式:
const plugin = require('tailwindcss/plugin')
module.exports = {
plugins: [
plugin(function({ addBase, theme }) {
addBase({
'h1': { fontSize: theme('fontSize.2xl') },
'h2': { fontSize: theme('fontSize.xl') },
'h3': { fontSize: theme('fontSize.lg') },
})
})
]
}由于基本样式旨在针对裸选择器,如 div 或 h1 ,它们不会遵循用户的 prefix 或 important 配置。
添加变体
addVariant 和 matchVariant 函数允许您注册自定义修饰符,这些修饰符可以像 hover 、 focus 或 supports 等内置变体一样使用。
静态变体
使用 addVariant 函数来创建简单的自定义变体,传入你的自定义变体的名称和表示选择器应如何修改的格式字符串。
const plugin = require('tailwindcss/plugin')
module.exports = {
// ...
plugins: [
plugin(function({ addVariant }) {
addVariant('optional', '&:optional')
addVariant('hocus', ['&:hover', '&:focus'])
addVariant('inverted-colors', '@media (inverted-colors: inverted)')
})
]
}第一个参数是用户在其 HTML 中将使用的修饰符名称,因此上面的示例将使得可以编写这样的类:
<form class="flex inverted-colors:outline ...">
<input class="optional:border-gray-300 ..." />
<button class="bg-blue-500 hocus:bg-blue-600">...</button>
</form>动态变体
使用 matchVariant 函数注册新的参数化变体,就像内置的 supports-* 、 data-* 和 aria-* 变体一样:
const plugin = require('tailwindcss/plugin')
module.exports = {
plugins: [
plugin(function({ matchVariant }) {
matchVariant(
'nth',
(value) => {
return `&:nth-child(${value})`;
},
{
values: {
1: '1',
2: '2',
3: '3',
}
}
);
})
]
}使用 matchVariant 定义的变体还支持使用方括号表示任意值:
<div class="nth-[3n+1]:bg-blue-500 ...">
<!-- ... -->
</div>如果需要控制生成的 CSS 的源顺序,以避免与来自相同变体的其他值的优先级问题,请使用 sort 选项:
matchVariant("min", (value) => `@media (min-width: ${value})`, {
sort(a, z) {
return parseInt(a.value) - parseInt(z.value);
},
});父级和同级状态
您的自定义修饰符不会自动与 Tailwind 的父级和同级状态修饰符配合使用。
要支持您自定义修饰符的 group-* 和 peer-* 版本,请使用特殊的 :merge 指令将它们注册为单独的变体,以确保最终选择器中只出现一次 .group 和 .peer 类。
const plugin = require('tailwindcss/plugin')
module.exports = {
// ...
plugins: [
plugin(function({ addVariant }) {
addVariant('optional', '&:optional')
addVariant('group-optional', ':merge(.group):optional &')
addVariant('peer-optional', ':merge(.peer):optional ~ &')
})
]
}扩展配置
插件可以通过在第二个参数中提供一个对象,将自己的配置值合并到用户的 tailwind.config.js 配置中:
const plugin = require('tailwindcss/plugin')
module.exports = plugin(function({ matchUtilities, theme }) {
matchUtilities(
{
tab: (value) => ({
tabSize: value
}),
},
{ values: theme('tabSize') }
)
}, {
theme: {
tabSize: {
1: '1',
2: '2',
4: '4',
8: '8',
}
}
})这对于为插件生成的类提供默认 theme 值等方面非常有用。
暴露选项
有时,插件可以以一种不太适合放在 theme 下的可配置方式进行配置,也许您希望用户能够自定义插件使用的类名。
对于这样的情况,您可以使用 plugin.withOptions 来定义一个可以使用配置对象调用的插件。此 API 类似于常规 plugin API,只是每个参数应该是一个接收用户 options 并返回通常使用常规 API 传递的值的函数:
const plugin = require('tailwindcss/plugin')
module.exports = plugin.withOptions(function (options = {}) {
return function({ addComponents }) {
const className = options.className ?? 'markdown'
addComponents({
[`.${className}`]: {
// ...
}
})
}
}, function (options) {
return {
theme: {
markdown: {
// ...
}
},
}
})用户在其 plugins 配置中注册插件时,会调用您的插件并传递他们的选项。
/** @type {import('tailwindcss').Config} */
module.exports = {
theme: {
// ...
},
plugins: [
require('./plugins/markdown.js')({
className: 'wysiwyg'
})
],
}如果用户不需要传递任何自定义选项,也可以正常注册以这种方式创建的插件,而无需调用它们
/** @type {import('tailwindcss').Config} */
module.exports = {
theme: {
// ...
},
plugins: [
require('./plugins/markdown.js')
],
}CSS-in-JS 语法
Tailwind 的插件系统期望将 CSS 规则编写为 JavaScript 对象,使用与 CSS-in-JS 库(如 Emotion)相似的语法,其底层由 postcss-js 提供支持。
请看这条简单的 CSS 规则:
.card {
background-color: #fff;
border-radius: .25rem;
box-shadow: 0 2px 4px rgba(0,0,0,0.2);
}将其翻译为 CSS-in-JS 对象将如下所示:
addComponents({
'.card': {
'background-color': '#fff',
'border-radius': '.25rem',
'box-shadow': '0 2px 4px rgba(0,0,0,0.2)',
}
})为了方便起见,属性名称也可以用驼峰写法,并且会自动翻译为短横线写法:
addComponents({
'.card': {
backgroundColor: '#fff',
borderRadius: '.25rem',
boxShadow: '0 2px 4px rgba(0,0,0,0.2)',
}
})嵌套也是支持的(由 postcss-nested 提供支持),使用与 Sass 或 Less 中熟悉的相同语法:
addComponents({
'.card': {
backgroundColor: '#fff',
borderRadius: '.25rem',
boxShadow: '0 2px 4px rgba(0,0,0,0.2)',
'&:hover': {
boxShadow: '0 10px 15px rgba(0,0,0,0.2)',
},
'@media (min-width: 500px)': {
borderRadius: '.5rem',
}
}
})可以在同一个对象中定义多个规则:
addComponents({
'.btn': {
padding: '.5rem 1rem',
borderRadius: '.25rem',
fontWeight: '600',
},
'.btn-blue': {
backgroundColor: '#3490dc',
color: '#fff',
'&:hover': {
backgroundColor: '#2779bd'
},
},
'.btn-red': {
backgroundColor: '#e3342f',
color: '#fff',
'&:hover': {
backgroundColor: '#cc1f1a'
},
},
})…或者作为对象数组,以便重复相同的键:
addComponents([
{
'@media (min-width: 500px)': {
// ...
}
},
{
'@media (min-width: 500px)': {
// ...
}
},
{
'@media (min-width: 500px)': {
// ...
}
},
])