1. 定制化
  2. 插件

概述

插件允许你为 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.

tailwind.config.js
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:

tailwind.config.js
/** @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

addUtilitiesmatchUtilities 函数允许你在 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:

tailwind.config.js
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:

tailwind.config.js
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

默认情况下,插件工具会自动尊重用户的 prefiximportant 首选项。

¥By default, plugin utilities automatically respect the user’s prefix and important preferences.

这意味着给定此 Tailwind 配置:

¥That means that given this Tailwind configuration:

tailwind.config.js
/** @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:

./plugins/tab-size.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',
    }
  }
})

这些值的行为就像默认配置中的值一样,可以由终端用户覆盖或扩展。

¥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:

tailwind.config.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 中。

¥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:

tailwind.config.js
/** @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:

tailwind.config.js
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:

tailwind.config.js
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:

tailwind.config.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') },
      })
    })
  ]
}

由于基本样式旨在针对像 divh1 这样的裸选择器,因此它们不尊重用户的 prefiximportant 配置。

¥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

addVariantmatchVariant 函数允许你注册自己的自定义 modifiers,它们可以像 hoverfocussupports 等内置变体一样使用。

¥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.

tailwind.config.js
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:

tailwind.config.js
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 的 parentsibling 状态修饰符一起使用。

¥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.

tailwind.config.js
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:

./plugins/tab-size.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 值之类的事情很有用。

¥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:

./plugins/markdown.js
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:

tailwind.config.js
/** @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:

tailwind.config.js
/** @type {import('tailwindcss').Config} */
module.exports = {
  theme: {
    // ...
  },
  plugins: [
    require('./plugins/markdown.js')
  ],
}

CSS-in-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)': {
      // ...
    }
  },
])