
定制化
使用可重用的第三方插件扩展 Tailwind。
插件允许你使用 JavaScript 而不是 CSS 为 Tailwind 注册新的样式,以注入到用户的样式表中。
🌐 Plugins let you register new styles for Tailwind to inject into the user’s stylesheet using JavaScript instead of CSS.
要开始使用你的第一个插件,从 tailwindcss/plugin 导入 Tailwind 的 plugin 函数。然后在你的 plugins 数组中,调用导入的 plugin 函数,并将一个匿名函数作为第一个参数传入。
🌐 To get started with your first plugin, import Tailwind’s plugin function from tailwindcss/plugin. Then inside your plugins array, call the imported plugin function with an anonymous function as the first argument.
const plugin = require('tailwindcss/plugin')
module.exports = {
plugins: [
plugin(function({ addUtilities, addComponents, e, config }) {
// Add your custom styles here
}),
]
}插件函数接收一个可以被解构为多个辅助函数的单一对象参数:
🌐 Plugin functions receive a single object argument that can be destructured into several helper functions:
addUtilities(),用于注册新的静态实用样式matchUtilities(),用于注册新的动态实用样式addComponents(),用于注册新的静态组件样式matchComponents(),用于注册新的动态组件样式addBase(),用于注册新的基本样式addVariant(),用于注册自定义静态变体matchVariant(),用于注册自定义动态变体theme(),用于查找用户主题配置中的值config(),用于查找用户 Tailwind 配置中的值corePlugins(),用于检查核心插件是否已启用e(),用于手动转义打算用于类名的字符串我们已经为一些流行功能开发了少量官方插件,这些功能由于某些原因尚不适合纳入核心。
🌐 We’ve developed a handful of official plugins for popular features that for one reason or another don’t belong in core yet.
可以通过 npm 安装插件,然后将它们添加到你的 tailwind.config.js 文件中,从而将插件添加到你的项目中:
🌐 Plugins can be added to your project by installing them via npm, then adding them to your tailwind.config.js file:
/** @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 数据库等来源的内容块添加合理的排版样式。
🌐 The @tailwindcss/typography plugin adds a set of prose classes that can be used to quickly add sensible typographic styles to content blocks that come from sources like markdown or a CMS database.
<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 插件添加了一个带有默认风格的表单重置层,使使用工具类来美化表单元素更加容易。
🌐 The @tailwindcss/forms plugin adds an opinionated form reset layer that makes it easier to style form elements with utility classes.
<!-- You can actually customize padding on a select element: -->
<select class="px-4 py-3 rounded-full">
<!-- ... -->
</select>
<!-- Or change a checkbox color using text color utilities: -->
<input type="checkbox" class="rounded text-pink-500" />
@tailwindcss/aspect-ratio 插件是原生 aspect-ratio 支持的替代方案,可在较旧的浏览器中使用,并添加了 aspect-w-* 和 aspect-h-* 类,这些类可以组合使用,为元素提供固定的纵横比。
🌐 The @tailwindcss/aspect-ratio plugin is an alternative to native aspect-ratio support that works in older browsers, and adds aspect-w-* and aspect-h-* classes that can be combined to give an element a fixed aspect ratio.
<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 的父元素的尺寸来为元素设置样式,而不是根据视口。
🌐 The @tailwindcss/container-queries plugin adds new @{size} variants like @sm and @md that let you style an element based on the dimensions of a parent marked with @container instead of the viewport.
<div class="@container">
<div class="@lg:text-sky-400">
<!-- ... -->
</div>
</div>
addUtilities 和 matchUtilities 函数允许你在 Tailwind 的 utilities 层中注册新样式。
🌐 The addUtilities and matchUtilities functions allow you to register new styles in Tailwind’s utilities layer.
就像 Tailwind 默认包含的工具类一样,插件添加的工具类只有在项目中实际使用时才会包含在生成的 CSS 中。
🌐 Like with the utilities Tailwind includes by default, utilities added by a plugin will only be included in the generated CSS if they are actually being used in the project.
使用 addUtilities 函数来注册不支持用户提供值的简单静态工具:
🌐 Use the addUtilities function to register simple static utilities that don’t support user-provided values:
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',
},
})
})
]
}了解更多关于如何在 JavaScript 中以 CSS-in-JS 语法 表示你的样式的信息。
🌐 Learn more about how to represent your styles in JavaScript in the CSS-in-JS syntax reference.
使用 matchUtilities 函数注册映射到用户 theme 配置中定义的值的工具:
🌐 Use the matchUtilities function to register utilities that map to values defined in the user’s theme configuration:
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') }
)
})
]
}以这种方式定义的实用程序还支持任意值,这意味着你可以使用主题中不存在的值,方法是使用方括号表示法:
🌐 Utilities defined this way also support arbitrary values, which means you can use values not present in the theme using square bracket notation:
<div class="tab-[13]">
<!-- ... -->
</div>
默认情况下,插件工具会自动遵循用户的 prefix 和 important 偏好设置。
🌐 By default, plugin utilities automatically respect the user’s prefix and important preferences.
这意味着在给定这个 Tailwind 配置的情况下:
🌐 That means that given this Tailwind configuration:
/** @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 添加的任何自定义工具都可以自动与修饰符一起使用:
🌐 Any custom utilities added using addUtilities can automatically be used with modifiers:
<div class="content-auto lg:content-visible">
<!-- ... -->
</div>
在悬停、聚焦及其他状态文档中了解更多信息。
🌐 Learn more in the Hover, Focus, and Other States documentation.
实用插件可以通过将配置对象作为 plugin 函数的第二个参数来提供默认值:
🌐 Utility plugins can provide default values by including a configuration object as the second argument to the plugin function:
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',
}
}
})这些值的行为就像默认配置中的值一样,并且可以由终端用户覆盖或扩展。
🌐 These values behave just like the values in the default configuration, and can be overridden or extended by the end user.
addComponents 函数允许你在 Tailwind 的 components 层中注册新样式。
🌐 The addComponents function allows you to register new styles in Tailwind’s components layer.
用它来添加更多有特定风格、复杂的类,如按钮、表单控件、警告等;这些是你在其他框架中常见的预构建组件,可能需要用工具类来覆盖。
🌐 Use it to add more opinionated, complex classes like buttons, form controls, alerts, etc; the sort of pre-built components you often see in other frameworks that you might need to override with utility classes.
要从插件添加新的组件样式,请调用 addComponents,并使用 CSS-in-JS 语法 传入你的样式:
🌐 To add new component styles from a plugin, call addComponents, passing in your styles using CSS-in-JS syntax:
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 中。
🌐 Like with other component classes in Tailwind, component classes added by a plugin will only be included in the generated CSS if they are actually being used in the project.
默认情况下,组件类会自动遵循用户的 prefix 偏好,但 它们不受 用户的 important 偏好影响。
🌐 By default, component classes automatically respect the user’s prefix preference, but they are not affected by the user’s important preference.
这意味着在给定这个 Tailwind 配置的情况下:
🌐 That means that given this Tailwind configuration:
/** @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:
🌐 Although there’s rarely a good reason to make component declarations important, if you really need to do it you can always add !important manually:
const plugin = require('tailwindcss/plugin')
module.exports = {
plugins: [
plugin(function({ addComponents }) {
addComponents({
'.btn': {
padding: '.5rem 1rem !important',
borderRadius: '.25rem !important',
fontWeight: '600 !important',
},
// ...
})
})
]
}选择器中的所有类默认都会添加前缀,因此如果你添加一个更复杂的样式,例如:
🌐 All classes in a selector will be prefixed by default, so if you add a more complex style like:
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 添加的任何组件类都可以自动与修饰符一起使用:
🌐 Any component classes added using addComponents can automatically be used with modifiers:
<div class="btn md:btn-lg">
<!-- ... -->
</div>
在悬停、聚焦及其他状态文档中了解更多信息。
🌐 Learn more in the Hover, Focus, and Other States documentation.
addBase 函数允许你在 Tailwind 的 base 层中注册新样式。使用它可以添加诸如基础排版样式、有针对性的全局重置或 @font-face 规则。
🌐 The addBase function allows you to register new styles in Tailwind’s base layer. Use it to add things like base typography styles, opinionated global resets, or @font-face rules.
要从插件添加新的基础样式,请调用 addBase,并使用 CSS-in-JS 语法 传入你的样式:
🌐 To add new base styles from a plugin, call addBase, passing in your styles using CSS-in-JS syntax:
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 配置。
🌐 Since base styles are meant to target bare selectors like div or h1, they do not respect the user’s prefix or important configuration.
addVariant 和 matchVariant 函数允许你注册自己的自定义 修饰符,它们可以像内置的 hover、focus 或 supports 一样使用。
🌐 The addVariant and matchVariant functions allow you to register your own custom modifiers that can be used just like built-in variants like hover, focus, or supports.
对于简单的自定义变体,使用 addVariant 函数,传入自定义变体的名称,以及表示选择器应如何修改的格式字符串。
🌐 Use the addVariant function for simple custom variants, passing in the name of your custom variant, and a format string that represents how the selector should be modified.
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 中使用的修饰符名称,因此上面的示例将使编写如下类成为可能:
🌐 The first argument is the modifier name that users will use in their HTML, so the above example would make it possible to write classes like these:
<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-* 变体一样:
🌐 Use the matchVariant function to register new parameterized variants like the built-in supports-*, data-*, and aria-* variants:
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 定义的变体也支持使用方括号表示任意值:
🌐 Variants defined with matchVariant also support arbitrary values using square bracket notation:
<div class="nth-[3n+1]:bg-blue-500 ...">
<!-- ... -->
</div>
如果需要避免与来自同一变体的其他值的优先级问题,可以使用 sort 选项来控制生成的 CSS 的源顺序:
🌐 Use the sort option to control the source order of the generated CSS if needed to avoid precedence issues with other values that come from the same variant:
matchVariant("min", (value) => `@media (min-width: ${value})`, {
sort(a, z) {
return parseInt(a.value) - parseInt(z.value);
},
});
你的自定义修饰符不会自动与 Tailwind 的 父元素 和 兄弟元素 状态修饰符一起生效。
🌐 Your custom modifiers won’t automatically work with Tailwind’s parent and sibling state modifiers.
为了支持你自定义修改器的 group-* 和 peer-* 版本,请使用特殊的 :merge 指令将它们注册为单独的变体,以确保 .group 和 .peer 类在最终选择器中只出现一次。
🌐 To support the group-* and peer-* versions of your own custom modifiers, register them as separate variants using the special :merge directive to ensure the .group and .peer classes only appear once in the final selector.
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 ~ &')
})
]
}
插件可以通过向 plugin 函数提供一个对象作为第二个参数,将它们自己的配置值集合合并到用户的 tailwind.config.js 配置中:
🌐 Plugins can merge their own set of configuration values into the user’s tailwind.config.js configuration by providing an object as the second argument to the plugin function:
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 值等情况非常有用。
🌐 This can be useful for things like providing default theme values for the classes your plugin generates.
有时候,让插件可以以某种方式进行配置是有意义的,即便这种配置不太适合放在 theme 下,比如你可能希望用户能够自定义你的插件使用的类名。
🌐 Sometimes it makes sense for a plugin to be configurable in a way that doesn’t really belong under theme, like perhaps you want users to be able to customize the class name your plugin uses.
对于这种情况,你可以使用 plugin.withOptions 来定义一个可以通过配置对象调用的插件。这个 API 类似于常规的 plugin API,不同之处在于每个参数应该是一个函数,该函数接收用户的 options 并返回你通常会使用常规 API 传入的值:
🌐 For cases like this, you can use plugin.withOptions to define a plugin that can be invoked with a configuration object. This API is similar to the regular plugin API, except each argument should be a function that receives the user’s options and returns the value that you would have normally passed in using the regular 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 配置时,会传递他们的选项来调用你的插件:
🌐 The user would invoke your plugin passing along their options when registering it in their plugins configuration:
/** @type {import('tailwindcss').Config} */
module.exports = {
theme: {
// ...
},
plugins: [
require('./plugins/markdown.js')({
className: 'wysiwyg'
})
],
}如果用户不需要传入任何自定义选项,也可以像平常一样注册以这种方式创建的插件,而不必调用它们:
🌐 The user can also register plugins created this way normally without invoking them if they don’t need to pass in any custom options:
/** @type {import('tailwindcss').Config} */
module.exports = {
theme: {
// ...
},
plugins: [
require('./plugins/markdown.js')
],
}Tailwind 的插件系统期望 CSS 规则以 JavaScript 对象的形式编写,使用的语法类似于你可能在 CSS-in-JS 库(如 Emotion)中看到的语法,底层由 postcss-js 提供支持。
🌐 Tailwind’s plugin system expects CSS rules written as JavaScript objects, using the same sort of syntax you might recognize from CSS-in-JS libraries like Emotion, powered by postcss-js under-the-hood.
考虑这个简单的 CSS 规则:
🌐 Consider this simple CSS rule:
.card {
background-color: #fff;
border-radius: .25rem;
box-shadow: 0 2px 4px rgba(0,0,0,0.2);
}
将其转换为 CSS-in-JS 对象看起来如下:
🌐 Translating this to a CSS-in-JS object would look like this:
addComponents({
'.card': {
'background-color': '#fff',
'border-radius': '.25rem',
'box-shadow': '0 2px 4px rgba(0,0,0,0.2)',
}
})
为了方便,属性名称也可以使用驼峰式书写,并会自动转换为短横线式:
🌐 For convenience, property names can also be written in camelCase and will be automatically translated to dash-case:
addComponents({
'.card': {
backgroundColor: '#fff',
borderRadius: '.25rem',
boxShadow: '0 2px 4px rgba(0,0,0,0.2)',
}
})
也支持嵌套(由 postcss-nested 提供支持),使用的语法与你可能熟悉的 Sass 或 Less 相同:
🌐 Nesting is also supported (powered by postcss-nested), using the same syntax you might be familiar with from Sass or 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',
}
}
})
可以在同一个对象中定义多个规则:
🌐 Multiple rules can be defined in the same object:
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)': {
// ...
}
},
])