概述

插件允许您使用 JavaScript(而不是 CSS)注册新的样式,以便 Tailwind 将其注入到用户的样式表中。

要开始使用您的第一个插件,请从 tailwindcss/plugin 中导入 Tailwind 的 plugin 函数。然后在您的 plugins 数组中,使用匿名函数作为第一个参数调用导入的 plugin 函数。

tailwind.config.js
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 文件中,将插件添加到您的项目中。

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 插件添加了一个有见地的表单重置层,使使用实用程序类样式化表单元素变得更加容易。

<!-- 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-{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>

了解更多关于容器查询插件的信息 →


添加实用程序

addUtilitiesmatchUtilities 函数允许您在 Tailwind 的 utilities 层中注册新的样式。

与 Tailwind 默认包含的实用程序类似,插件添加的实用程序只有在项目中实际使用时才会包含在生成的 CSS 中。

静态实用程序

使用 addUtilities 函数注册不支持用户提供值的简单静态实用程序

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

详细了解如何在 JavaScript 中表示样式,请参阅 CSS-in-JS 语法 参考。

动态实用程序

使用 matchUtilities 函数注册映射到用户 theme 配置中定义的值的实用程序

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') }
      )
    })
  ]
}

以这种方式定义的实用程序还支持 任意值,这意味着您可以使用主题中不存在的值,使用方括号表示法

<div class="tab-[13]">
  <!-- ... -->
</div>

前缀和重要

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

这意味着,给定此 Tailwind 配置

tailwind.config.js
/** @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函数来提供默认值。

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

这些值的行为与默认配置中的值相同,并且可以被最终用户覆盖或扩展。


添加组件

addComponents函数允许您在 Tailwind 的components层中注册新的样式。

使用它来添加更多有见地的、复杂的类,如按钮、表单控件、警报等;您经常在其他框架中看到的预构建组件,您可能需要使用实用程序类来覆盖它们。

要从插件添加新的组件样式,请调用addComponents,并使用CSS-in-JS 语法传递您的样式。

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 中。

前缀和重要

默认情况下,组件类会自动尊重用户的prefix首选项,但不会受到用户important首选项的影响。

这意味着,给定此 Tailwind 配置

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

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

选择器中的所有类默认情况下都会添加前缀,因此,如果您添加更复杂的样式,例如

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

.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 语法 传入您的样式

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 配置。


添加变体

addVariantmatchVariant 函数允许您注册您自己的自定义 修饰符,这些修饰符可以像内置变体(如 hoverfocussupports)一样使用。

静态变体

对于简单的自定义变体,请使用 addVariant 函数,传入您的自定义变体的名称和表示如何修改选择器的格式字符串。

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 中使用的修饰符名称,因此上面的示例将使编写以下类成为可能

<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-* 变体

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` 定义的变体也支持使用方括号表示法定义任意值。

<div class="nth-[3n+1]:bg-blue-500 ...">
  <!-- ... -->
</div>

如果需要避免与来自相同变体的其他值的优先级问题,请使用 `sort` 选项来控制生成的 CSS 的源顺序。

matchVariant("min", (value) => `@media (min-width: ${value})`, {
  sort(a, z) {
    return parseInt(a.value) - parseInt(z.value);
  },
});

父级和兄弟级状态

您的自定义修饰符不会自动与 Tailwind 的 父级兄弟级 状态修饰符一起使用。

要支持您自己的自定义修饰符的 `group-*` 和 `peer-*` 版本,请使用特殊的 `:merge` 指令将它们注册为单独的变体,以确保 `group` 和 `peer` 类仅在最终选择器中出现一次。

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 ~ &')
    })
  ]
}

扩展配置

插件可以通过将对象作为 `plugin` 函数的第二个参数提供,将它们自己的配置值集合并到用户的 `tailwind.config.js` 配置中。

./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` 值等情况很有用。


公开选项

有时,插件以一种不属于theme的方式进行配置是有意义的,例如,您可能希望用户能够自定义插件使用的类名。

对于这种情况,您可以使用plugin.withOptions来定义一个可以使用配置对象调用的插件。此 API 与常规的plugin API 类似,只是每个参数都应该是一个函数,该函数接收用户的options并返回您通常使用常规 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配置中注册插件时,会传递他们的选项来调用您的插件。

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

如果用户不需要传入任何自定义选项,他们也可以像往常一样注册以这种方式创建的插件,而无需调用它们。

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

CSS-in-JS 语法

Tailwind 的插件系统期望使用 JavaScript 对象编写 CSS 规则,使用与您可能从 Emotion 等 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)',
  }
})

为了方便起见,属性名称也可以用 camelCase 编写,并将自动转换为 dash-case

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