Tailwind CSS 插件

2022-08-08 10:11 更新

插件

使用可复用的第三方插件扩展 Tailwind。


插件让您注册新的样式,让 Tailwind 使用 JavaScript 代替 CSS 注入用户的样式表。

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

// tailwind.config.js
const plugin = require('tailwindcss/plugin')

module.exports = {
  plugins: [
    plugin(function({ addUtilities, addComponents, e, prefix, config }) {
      // Add your custom styles here
    }),
  ]
}

插件函数接收一个单一的对象参数,可以 destructured 成几个帮助函数。

  • addUtilities()​, 用于注册新的实用程序样式(for registering new utility styles)
  • addComponents()​, 用于注册新的组件样式for registering new component styles)
  • addBase()​, 用于注册新的基本样式(for registering new base styles)
  • addVariant()​, 用于注册自定义变体(for registering custom variants)
  • e()​, 用于转义用于类名的字符串(for escaping strings meant to be used in class names)
  • prefix()​, 用于手动将用户配置的前缀应用于选择器的某些部分(for manually applying the user’s configured prefix to parts of a selector)
  • theme()​, 用于在用户的主题配置中查找值(for looking up values in the user’s theme configuration)
  • variants()​, 用于在用户的变体配置中查找值(for looking up values in the user’s variants configuration)
  • config()​, 用于在用户的 Tailwind 配置中查找值(for looking up values in the user’s Tailwind configuration)
  • postcss​, 用于直接使用 PostCSS 进行低级操作(for doing low-level manipulation with PostCSS directly)

官方插件

我们已经开发了一些官方插件用于流行的功能,由于某种原因,这些插件还不属于核心。

可以通过 npm 安装插件,然后将它们添加到您的 ​tailwind.config.js​ 文件中,从而将它们添加到您的项目中:

// tailwind.config.js
module.exports = {
  // ...
  plugins: [
    require('@tailwindcss/typography'),
    require('@tailwindcss/forms'),
    require('@tailwindcss/line-clamp'),
    require('@tailwindcss/aspect-ratio'),
  ]
}

Typography

@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>

了解有关typography插件的更多信息 

Forms

@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" />

了解有关forms插件的更多信息

Line-clamp

@tailwindcss/line-clamp​ 插件添加了 ​line-clamp-{lines}​ 类,可用于将文本截断为固定行数。

<p class="line-clamp-3 md:line-clamp-none">
  Et molestiae hic earum repellat aliquid est doloribus delectus. Enim illum odio porro ut omnis
  dolor debitis natus. Voluptas possimus deserunt sit delectus est saepe nihil. Qui voluptate
  possimus et quia. Eligendi voluptas voluptas dolor cum. Rerum est quos quos id ut molestiae fugit.
</p>

了解有关line-clamp插件的更多信息

Aspect ratio

@tailwindcss/aspect-ratio​ 插件添加了 ​aspect-w-{n}​ 和 ​aspect-h-{n}​ 类,它们可以组合起来为元素提供固定的宽高比。

<div class="aspect-w-16 aspect-h-9">
  <iframe src="https://www.youtube.com/embed/dQw4w9WgXcQ" rel="external nofollow"  frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>
</div>

了解有关aspect ratio插件的更多信息

Adding utilities

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

插件功能类的输出顺序是按照其注册的顺序,在内置的功能类之后,所以如果一个插件的作用目标是任何一个与内置功能类相同的属性,插件功能类将优先。

要从插件中添加新的功能类,调用 ​addUtilities​,使用 CSS-in-JS 语法 传递您的样式。

// tailwind.config.js
const plugin = require('tailwindcss/plugin')

module.exports = {
  plugins: [
    plugin(function({ addUtilities }) {
      const newUtilities = {
        '.skew-10deg': {
          transform: 'skewY(-10deg)',
        },
        '.skew-15deg': {
          transform: 'skewY(-15deg)',
        },
      }

      addUtilities(newUtilities)
    })
  ]
}

前缀 和 important 参考

默认情况下,插件功能类会自动遵守用户的 ​prefix ​和 ​important ​偏好。

也就是说,如果给出这样的 Tailwind 配置:

// tailwind.config.js
module.exports = {
  prefix: 'tw-',
  important: true,
  // ...
}

上面的示例插件会生成以下CSS:

.tw-skew-10deg {
  transform: skewY(-10deg) !important;
}
.tw-skew-15deg {
  transform: skewY(-15deg) !important;
}

如果有必要,您可以通过向 ​addUtilities ​传递一个选项对象作为第二个参数来选择不使用这种行为。

// tailwind.config.js
const plugin = require('tailwindcss/plugin')

module.exports = {
  plugins: [
    plugin(function({ addUtilities }) {
      const newUtilities = {
        // ...
      }

      addUtilities(newUtilities, {
        respectPrefix: false,
        respectImportant: false,
      })
    })
  ]
}

变体

要生成 responsive、hover、focus、active 或样式的其它变体,请使用 ​variants ​选项指定您想生成的变体。

// tailwind.config.js
const plugin = require('tailwindcss/plugin')

module.exports = {
  plugins: [
    plugin(function({ addUtilities }) {
      const newUtilities = {
        // ...
      }

      addUtilities(newUtilities, {
        variants: ['responsive', 'hover'],
      })
    })
  ]
}

如果您只需要指定变体,而不需要选择不使用默认的前缀或 important 选项,您也可以直接将变体数组作为第二个参数传递。

// tailwind.config.js
const plugin = require('tailwindcss/plugin')

module.exports = {
  plugins: [
    plugin(function({ addUtilities }) {
      const newUtilities = {
        // ...
      }

      addUtilities(newUtilities, ['responsive', 'hover'])
    })
  ]
}

如果您希望用户在他们的 ​tailwind.config.js​ 文件中的 ​variants ​部分提供自己的变体,您可以使用 ​variants()​ 函数来获取他们配置的变体。

// tailwind.config.js
const plugin = require('tailwindcss/plugin')

module.exports = {
  variants: {
    customPlugin: ['responsive', 'hover'],
  },
  plugins: [
    plugin(function({ addUtilities, variants }) {
      const newUtilities = {
        // ...
      }

      addUtilities(newUtilities, variants('customPlugin'))
    })
  ]
}

增加组件

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

用它来添加更个性化、更复杂的类,比如按钮、表单控件、警告等;就是您在其他框架中经常看到的您可能需要使用功能类覆盖的那种预建组件。

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

// tailwind.config.js
const plugin = require('tailwindcss/plugin')

module.exports = {
  plugins: [
    plugin(function({ addComponents }) {
      const buttons = {
        '.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(buttons)
    })
  ]
}

前缀 和 important 参考

默认情况下,组件类自动遵守用户的 ​prefix ​偏好,但不受用户的 ​important ​偏好的影响。

这意味着如果有以下 Tailwind 配置:

// tailwind.config.js
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,但如果您真的需要这样做,您可以手动添加 ​!important​ 。

// tailwind.config.js
const plugin = require('tailwindcss/plugin')

module.exports = {
  plugins: [
    plugin(function({ addComponents }) {
      const buttons = {
        '.btn': {
          padding: '.5rem 1rem !important',
          borderRadius: '.25rem !important',
          fontWeight: '600 !important',
        },
        // ...
      }

      addComponents(buttons)
    })
  ]
}

选择器中的所有类都会默认添加前缀,所以如果您添加一个更复杂的样式,比如:

// 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;
}

要选择不使用前缀,可以传递一个 options 对象作为第二个参数给 ​addComponents​:

// tailwind.config.js
const plugin = require('tailwindcss/plugin')

module.exports = {
  prefix: 'tw-',
  plugins: [
    plugin(function({ addComponents }) {
      const components = {
        // ...
      }

      addComponents(components, {
        respectPrefix: false
      })
    })
  ]
}

变体

要生成组件的 responsive、hover、focus、active或其他变体,请使用 ​variants ​选项指定您想生成的变体。

// tailwind.config.js
const plugin = require('tailwindcss/plugin')

module.exports = {
  plugins: [
    plugin(function({ addComponents }) {
      const newComponents = {
        // ...
      }

      addComponents(newComponents, {
        variants: ['responsive', 'hover'],
      })
    })
  ]
}

如果您只需要指定变体,而不需要选择不使用默认的前缀或 important 选项,您也可以直接将变体数组作为第二个参数传递。

// tailwind.config.js
const plugin = require('tailwindcss/plugin')

module.exports = {
  plugins: [
    plugin(function({ addComponents }) {
      const newComponents = {
        // ...
      }

      addComponents(newComponents, ['responsive', 'hover'])
    })
  ]
}

如果您希望用户在他们的 ​tailwind.config.js​ 文件中的 ​variants ​部分提供自己的变体,您可以使用 ​variants()​ 函数来获取他们配置的变体。

// tailwind.config.js
const plugin = require('tailwindcss/plugin')

module.exports = {
  variants: {
    customPlugin: ['responsive', 'hover'],
  },
  plugins: [
    plugin(function({ addComponents, variants }) {
      const newComponents = {
        // ...
      }

      addComponents(newComponents, variants('customPlugin'))
    })
  ]
}

添加基础样式

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

由于基本样式是针对 ​div​、​h1 ​等裸选择器的,所以它们不遵从用户的 ​prefix ​或 ​important ​配置。

转义类名

如果您的插件生成的类中包含用户提供的字符串,您可以使用 ​e​ 函数来转义这些类名,以确保非标准字符被正确地自动处理。

例如,这个插件生成了一组 ​.rotate-{angle}​ 功能类,其中 ​{angle}​ 是用户提供的字符串。​e​ 函数用于转义连接的类名,以确保像 ​.rotate-1/4​ 这样的类能按预期工作。

// tailwind.config.js
const _ = require('lodash')
const plugin = require('tailwindcss/plugin')

module.exports = {
  theme: {
    rotate: {
      '1/4': '90deg',
      '1/2': '180deg',
      '3/4': '270deg',
    }
  },
  plugins: [
    plugin(function({ addUtilities, theme, e }) {
      const rotateUtilities = _.map(theme('rotate'), (value, key) => {
        return {
          [`.${e(`rotate-${key}`)}`]: {
            transform: `rotate(${value})`
          }
        }
      })

      addUtilities(rotateUtilities)
    })
  ]
}

这个插件会生成以下CSS:

.rotate-1\/4 {
  transform: rotate(90deg);
}
.rotate-1\/2 {
  transform: rotate(180deg);
}
.rotate-3\/4 {
  transform: rotate(270deg);
}

注意只转义您真正想转义的内容;不要在类名中传递前导的 ​.​ 或在 ​:hover​ 或 ​:focus​ 等伪类的开头传递 ​:​,否则这些字符将被转义。

此外,因为 CSS 有关于类名的规则(类名不能以数字开头,但可以包含数字),所以最好是转义完整的类名(不只是用户提供的部分),否则您可能会得到不必要的转义序列。

// Will unnecessarily escape `1`
`.rotate-${e('1/4')}`
// => '.rotate-\31 \/4'

// Won't escape `1` because it's not the first character
`.${e('rotate-1/4')}`
// => '.rotate-1\/4'

手动给选择器加前缀

如果您正在写一些复杂的东西,您只想给某些类加前缀,您可以使用 ​prefix ​函数来精细控制何时应用用户配置的前缀。

例如,如果您正在创建一个插件,以便在一组内部项目中重复使用,在其选择器中包含现有的类,您可能只想给新的类加上前缀。

// tailwind.config.js
const plugin = require('tailwindcss/plugin')

module.exports = {
  prefix: 'tw-',
  plugins: [
    plugin(function({ addComponents, prefix }) {
      addComponents({
        [`.existing-class > ${prefix('.new-class')}`]: {
          backgroundColor: '#fff',
        }
      })
    })
  ]
}

这将生成以下CSS:

.existing-class > .tw-new-class {
  background-color: #fff;
}

prefix ​函数会给选择器中的所有类加前缀,而忽略不是类的选择器,所以传递像这样复杂的选择器是完全安全的。

prefix('.btn-blue .w-1\/4 > h1.text-xl + a .bar')
// => '.tw-btn-blue .tw-w-1\/4 > h1.tw-text-xl + a .tw-bar'

引用用户配置

config​、​theme ​和 ​variants ​函数允许您使用点符号从用户的 Tailwind 配置中获取一个值,如果该路径不存在,则提供一个默认值。

例如,这个简化版的内置 容器 插件使用 ​theme ​函数来获取用户配置的断点。

// tailwind.config.js
const _ = require('lodash')
const plugin = require('tailwindcss/plugin')

module.exports = {
  plugins: [
    plugin(function({ addComponents, theme }) {
      const screens = theme('screens', {})

      const mediaQueries = _.map(screens, width => {
        return {
          [`@media (min-width: ${width})`]: {
            '.container': {
              'max-width': width,
            },
          },
        }
      })

      addComponents([
        { '.container': { width: '100%' } },
        ...mediaQueries,
      ])
    })
  ]
}

如果你想引用用户的 ​variables ​配置,建议你使用 ​variables()​ 函数而不是 config 函数。

不要使用 config 函数来查找变体

addUtilities(newUtilities, config('variants.customPlugin'))

使用 variants 函数代替

addUtilities(newUtilities, variants('customPlugin'))

由于 ​variants ​可以简单地成为一个全局的变体列表,为整个项目中的每一个插件进行配置,所以使用 ​variants()​ 函数可以让您很容易地遵从用户的配置,而不是自己重新实现这个逻辑。

// tailwind.config.js
const plugin = require('tailwindcss/plugin')

module.exports = {
  variants: ['responsive', 'hover', 'focus'],
  plugins: [
    plugin(function ({ config, variants }) {
      config('variants.customPlugin')
      // => undefined

      variants('customPlugin')
      // => ['responsive', 'hover', 'focus']
    })
  ]
}

暴露选项

通常情况下,一个插件暴露自己的选项是有意义的,用户可以配置这些选项来定制插件的行为。

最好的方法是在用户的 ​theme ​和 ​variants ​配置中定义自己的键,并要求他们在那里提供任何选项,这样您就可以通过 ​theme ​和 ​variants ​函数访问它们。

例如,这里有一个插件(提取到自己的模块),用于创建简单的渐变功能类,接受要生成的渐变值和变体做为选项。

// ./plugins/gradients.js
const _ = require('lodash')
const plugin = require('tailwindcss/plugin')

module.exports = plugin(function({ addUtilities, e, theme, variants }) {
  const gradients = theme('gradients', {})
  const gradientVariants = variants('gradients', [])

  const utilities = _.map(gradients, ([start, end], name) => ({
    [`.${e(`bg-gradient-${name}`)}`]: {
      backgroundImage: `linear-gradient(to right, ${start}, ${end})`
    }
  }))

  addUtilities(utilities, gradientVariants)
})

要使用它,您需要在您的插件列表中 ​require ​它,在 ​theme ​和 ​variants ​中的 ​gradients ​键下指定您的配置。

// tailwind.config.js
module.exports = {
  theme: {
    gradients: theme => ({
      'blue-green': [theme('colors.blue.500'), theme('colors.green.500')],
      'purple-blue': [theme('colors.purple.500'), theme('colors.blue.500')],
      // ...
    })
  },
  variants: {
    gradients: ['responsive', 'hover'],
  },
  plugins: [
    require('./plugins/gradients')
  ],
}

提供默认选项

要为您的插件提供默认的 ​theme ​和 ​variants ​选项,请向 Tailwind 的 ​plugin ​函数传递包含默认值的第二个参数,。

// ./plugins/gradients.js
const _ = require('lodash')
const plugin = require('tailwindcss/plugin')

module.exports = plugin(function({ addUtilities, e, theme, variants }) {
  // ...
}, {
  theme: {
    gradients: theme => ({
      'blue-green': [theme('colors.blue.500'), theme('colors.green.500')],
      'purple-blue': [theme('colors.purple.500'), theme('colors.blue.500')],
      // ...
    })
  },
  variants: {
    gradients: ['responsive', 'hover'],
  }
})

这个对象只是另一个 Tailwind 配置对象,并具有与 ​tailwind.config.js​ 中使用的配置对象相同的所有属性和功能。

通过以这种方式提供您的默认值,最终用户将能够 覆盖 和 扩展 您的默认值,就像他们可以覆盖扩展 Tailwind 的内置样式一样。

公开高级配置选项

有时,以不真正属于 ​theme ​或 ​variants ​的方式配置插件是有意义的,例如您可能希望用户能够自定义插件使用的类名。

对于这种情况,您可以使用 ​plugin.withOptions​ 来定义一个可以使用配置对象调用的插件。此 API 类似于常规插件 API,除了每个参数应该是一个函数,它接收用户的选项并返回您通常使用常规 API 传入的值:

// ./plugins/gradients.js
const _ = require('lodash')
const plugin = require('tailwindcss/plugin')

module.exports = plugin.withOptions(function (options) {
  return function({ addUtilities, e, theme, variants }) {
    const classPrefix = options.classPrefix ?? 'bg-gradient'
    const gradients = theme('gradients', {})
    const gradientVariants = variants('gradients', [])

    const utilities = _.map(gradients, ([start, end], name) => ({
      [`.${e(`${classPrefix}-${name}`)}`]: {
        backgroundImage: `linear-gradient(to right, ${start}, ${end})`
      }
    }))

    addUtilities(utilities, gradientVariants)
  }
}, function (options) {
  return {
    theme: {
      gradients: theme => ({
        'blue-green': [theme('colors.blue.500'), theme('colors.green.500')],
        'purple-blue': [theme('colors.purple.500'), theme('colors.blue.500')],
        // ...
      })
    },
    variants: {
      gradients: ['responsive', 'hover'],
    }
  }
})

用户在他们的插件配置中注册你的插件时,会调用你的插件并传递他们的选项。

// tailwind.config.js
module.exports = {
  theme: {
    // ...
  },
  variants: {
    // ...
  },
  plugins: [
    require('./plugins/gradients')({
      classPrefix: 'bg-grad'
    })
  ],
}

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

// tailwind.config.js
module.exports = {
  theme: {
    // ...
  },
  variants: {
    // ...
  },
  plugins: [
    require('./plugins/gradients')
  ],
}

CSS-in-JS 语法

每一个 ​addUtilities​、​addComponents ​和 ​addBase ​都期望 CSS 规则写成 JavaScript 对象。Tailwind 使用的语法,您可能会从 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)': {
      // ...
    }
  },
])

增加变体

addVariant ​函数允许您注册自己的自定义 变体,这些变体可以像内置的 hover、hover、hover 等变体一样使用。

要添加一个新的变量,调用 ​addVariant ​函数,传入您的自定义变量的名称,以及一个回调,根据需要修改受影响的 CSS 规则。

const plugin = require('tailwindcss/plugin')

module.exports = {
  plugins: [
    plugin(function({ addVariant, e }) {
      addVariant('disabled', ({ modifySelectors, separator }) => {
        modifySelectors(({ className }) => {
          return `.${e(`disabled${separator}${className}`)}:disabled`
        })
      })
    })
  ]
}

回调收到的对象可以被反构为以下部分:

  • modifySelectors, 用于简化添加基本变体的辅助函数(a helper function to simplify adding basic variants)
  • separator,用户配置的分隔符字符串(the user’s configured separator string)
  • container, 一个 PostCSS 容器,包含应用变体的所有规则,用于创建复杂的变体(a PostCSS Container containing all of the rules the variant is being applied to, for creating complex variants)

基本变体

如果您想添加一个简单的变量,只需要改变选择器,使用 ​modifySelectors ​助手。

modifySelectors ​助手接受一个函数,该函数接收一个对象,该对象可以被重构为以下部分:

  • selector​, 当前规则的完整未修改选择器(the complete unmodified selector for the current rule)
  • className​, 当前规则的类名,去掉了前导点(the class name of the current rule with the leading dot removed)

您传递给 ​modifySelectors ​的函数应该简单地返回修改后的选择器。

例如,一个 ​first-child​ 的变体插件可以这样写:

// tailwind.config.js
const plugin = require('tailwindcss/plugin')

module.exports = {
  plugins: [
    plugin(function({ addVariant, e }) {
      addVariant('first-child', ({ modifySelectors, separator }) => {
        modifySelectors(({ className }) => {
          return `.${e(`first-child${separator}${className}`)}:first-child`
        })
      })
    })
  ]
}

复杂变体

如果您需要做的事情不仅仅是简单地修改选择器(比如改变实际的规则声明,或者将规则包装在另一个 at-rule 中),您将需要使用 ​container ​实例。

使用 ​container ​实例,您可以在给定的模块或 ​@variants​ 块中遍历所有的规则,并使用标准的 PostCSS API 随意操作它们。

例如,该插件通过在类前加上感叹号,并将每个声明修改为 ​important​,为每个受影响的功能创建一个 ​important ​版本。

// tailwind.config.js
const plugin = require('tailwindcss/plugin')

module.exports = {
  plugins: [
    plugin(function({ addVariant }) {
      addVariant('important', ({ container }) => {
        container.walkRules(rule => {
          rule.selector = `.\\!${rule.selector.slice(1)}`
          rule.walkDecls(decl => {
            decl.important = true
          })
        })
      })
    })
  ]
}

这个插件将容器内的所有规则,用 ​@supports (display: grid)​ at-rule 包装起来,并在每个规则前加上 ​supports-grid​ 。

// tailwind.config.js
const plugin = require('tailwindcss/plugin')

module.exports = {
  plugins: [
    plugin(function({ addVariant, e, postcss }) {
      addVariant('supports-grid', ({ container, separator }) => {
        const supportsRule = postcss.atRule({ name: 'supports', params: '(display: grid)' })
        supportsRule.append(container.nodes)
        container.append(supportsRule)
        supportsRule.walkRules(rule => {
          rule.selector = `.${e(`supports-grid${separator}`)}${rule.selector.slice(1)}`
        })
      })
    })
  ]
}

要了解更多关于直接使用 PostCSS 的信息,请查看 PostCSS API 文档

使用自定义变体

使用自定义变体与使用 Tailwind 的内置变体没有什么不同。

要使定制的变体与 Tailwind 的核心插件一起使用,将它们添加到您的配置文件的 ​variants ​部分。

// tailwind.config.js
modules.exports = {
  variants: {
    borderWidths: ['responsive', 'hover', 'focus', 'first-child', 'disabled'],
  }
}

要在您自己的CSS中使自定义变体和自定义功能类一起使用,请使用 variants at-rule

@variants hover, first-child {
  .bg-cover-image {
    background-image: url('/path/to/image.jpg');
  }
}


以上内容是否对您有帮助:
在线笔记
App下载
App下载

扫描二维码

下载编程狮App

公众号
微信公众号

编程狮公众号