定制化
使用可重用的第三方插件扩展 Tailwind。
插件允许你为 Tailwind 注册新样式,以使用 JavaScript 而不是 CSS 注入用户的样式表。
¥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
}),
]
}
插件函数接收一个对象参数,它可以是 destructured 到几个辅助函数中:
¥Plugin functions receive a single object argument that can be destructured into several helper functions:
addUtilities()
,用于注册新的静态工具样式
¥addUtilities()
, for registering new static utility styles
matchUtilities()
,用于注册新的动态工具样式
¥matchUtilities()
, for registering new dynamic utility styles
addComponents()
,用于注册新的静态组件样式
¥addComponents()
, for registering new static component styles
matchComponents()
,用于注册新的动态组件样式
¥matchComponents()
, for registering new dynamic component styles
addBase()
,用于注册新的基础样式
¥addBase()
, for registering new base styles
addVariant()
,用于注册自定义静态变体
¥addVariant()
, for registering custom static variants
matchVariant()
,用于注册自定义动态变体
¥matchVariant()
, for registering custom dynamic variants
theme()
,用于查找用户主题配置中的值
¥theme()
, for looking up values in the user’s theme configuration
config()
,用于在用户的 Tailwind 配置中查找值
¥config()
, for looking up values in the user’s Tailwind configuration
corePlugins()
,用于检查核心插件是否启用
¥corePlugins()
, for checking if a core plugin is enabled
e()
,用于手动转义用于类名的字符串
¥e()
, for manually escaping strings meant to be used in class names
¥Official plugins
我们已经为流行的功能开发了一些官方插件,这些功能由于某种原因还不属于核心。
¥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'),
]
}
¥Typography
@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>
¥Learn more about the typography plugin →
¥Forms
@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" />
¥Learn more about the forms plugin →
¥Aspect ratio
@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>
¥Learn more about the aspect ratio plugin →
¥Container queries
@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>
¥Learn more about the container queries plugin →
¥Adding utilities
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.
¥Static utilities
使用 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',
},
})
})
]
}
在 CSS-in-JS 语法 参考中了解有关如何在 JavaScript 中表示样式的更多信息。
¥Learn more about how to represent your styles in JavaScript in the CSS-in-JS syntax reference.
¥Dynamic utilities
使用 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 and important
默认情况下,插件工具会自动尊重用户的 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:
¥…the example plugin above would generate the following CSS:
.tw-content-auto {
content-visibility: auto !important;
}
.tw-content-hidden {
content-visibility: hidden !important;
}
.tw-content-visible {
content-visibility: visible !important;
}
¥Using with modifiers
使用 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.
¥Providing default values
工具插件可以通过包含一个配置对象作为 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.
¥Adding components
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 and important
默认情况下,组件类自动尊重用户的 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:
¥…the example plugin above would generate the following 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:
¥…the following CSS would be generated:
.tw-navbar-inverse a.tw-nav-link {
color: #fff;
}
¥Using with modifiers
使用 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.
¥Adding base styles
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.
¥Adding variants
addVariant
和 matchVariant
函数允许你注册自己的自定义 modifiers,它们可以像 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
.
¥Static variants
将 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>
¥Dynamic variants
使用 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);
},
});
¥Parent and sibling states
你的自定义修饰符不会自动与 Tailwind 的 parent 和 sibling 状态修饰符一起使用。
¥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 ~ &')
})
]
}
¥Extending the configuration
通过提供一个对象作为 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.
¥Exposing options
有时,以不真正属于 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')
],
}
¥CSS-in-JS syntax
Tailwind 的插件系统期望将 CSS 规则编写为 JavaScript 对象,使用你可能从 CSS-in-JS 库(如 情感)中识别的相同类型的语法,由 postcss-js under-the-hood 提供支持。
¥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'
},
},
})
…或者作为对象数组,以防你需要重复相同的键:
¥…or as an array of objects in case you need to repeat the same key:
addComponents([
{
'@media (min-width: 500px)': {
// ...
}
},
{
'@media (min-width: 500px)': {
// ...
}
},
{
'@media (min-width: 500px)': {
// ...
}
},
])