Just-in-Time: Следующее поколение Tailwind CSS
Tailwind CSS на GitHubTailwind CSS в Telegram

Плагины

Расширение Tailwind с помощью переиспользуемых сторонних плагинов.

Обзор

Плагины позволяют регистрировать новые стили для Tailwind для внедрения в таблицу стилей пользователя с использованием JavaScript вместо CSS.

Чтобы начать работу с Вашим первым плагином, импортируйте функцию Tailwind plugin из tailwindcss/plugin. Затем внутри Вашего массива plugins и вызовите его с анонимной функцией в качестве первого аргумента.

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

module.exports = {
  plugins: [
    plugin(function({ addUtilities, addComponents, e, prefix, config }) {
      // Добавьте сюда свои собственные стили
    }),
  ]
}

Функции плагина получают один аргумент объекта, который может быть деструктурирован в несколько вспомогательных функций:

  • addUtilities(), для регистрации новых утилит стилей
  • addComponents(), для регистрации новых компонентов стилей
  • addBase(), для регистрации новых базовых стилей
  • addVariant(), для регистрации пользовательских вариантов
  • e(), для экранирования строк, предназначенных для использования в именах классов
  • prefix(), для ручного применения настроенного пользователем префикса к частям селектора
  • theme(), для поиска значений в конфигурации темы пользователя
  • variants(), для поиска значений в конфигурации вариантов пользователя
  • config(), для поиска значений в пользовательской конфигурации Tailwind
  • postcss, для выполнения напрямую низкоуровневых манипуляций с PostCSS

Официальные плагины

Мы разработали несколько официальных плагинов для популярных функций, которые по тем или иным причинам еще не входят в состав ядра.

Плагины могут быть добавлены в ваш проект, установив их через npm, а затем добавив их в ваш файл tailwind.config.js:

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

Типография

Плагин @tailwindcss/typography добавляет набор классов prose, которые можно использовать для быстрого добавления разумных типографских стилей к блокам контента, которые поступают из таких источников, как маркдаун или база данных CMS.

<article class="prose lg:prose-xl">
  <h1>Чесночный хлеб с сыром: что нам подсказывает наука</h1>
  <p>
    В течение многих лет родители защищали своих детей от употребления чесночного хлеба с сыром о пользе для здоровья, и эта еда приобрела такой знаковый статус в нашей культуре, что дети часто наряжаются в теплые сырные буханки на Хэллоуин.
  </p>
  <p>
    Но недавнее исследование показывает, что знаменитая закуска может быть связана с серией случаев заболевания бешенством, возникающих по всей стране.
  </p>
  <!-- ... -->
</article>

Узнать больше о плагине типографики

Формы

Плагин @tailwindcss/forms добавляет упорядоченный уровень сброса формы, который упрощает стилизацию элементов формы с помощью классов утилит.

<!-- Фактически вы можете настроить отступы для выбранного элемента: -->
<select class="px-4 py-3 rounded-full">
  <!-- ... -->
</select>

<!-- Или измените цвет флажка с помощью утилит для настройки цвета текста: -->
<input type="checkbox" class="rounded text-pink-500" />

Узнать больше о плагине форм

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

Соотношение сторон

Плагин @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" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>
</div>

Узнать больше о плагине соотношения сторон


Добавление утилит

Функция addUtilities позволяет вам регистрировать новые стили в слое utilities Tailwind.

Утилиты плагинов выводятся в порядке их регистрации, после встроенных утилит, поэтому, если плагин нацелен на любое из тех же свойств, что и встроенная утилита, утилита плагина будет иметь приоритет.

Чтобы добавить новые утилиты из плагина, вызовите 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)
    })
  ]
}

Префикс и важные настройки

По умолчанию утилиты плагинов автоматически учитывают предпочтения пользователя 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,
      })
    })
  ]
}

Варианты

Чтобы сгенерировать адаптивный, наведение, фокус, активный или другие варианты Ваших стилей, укажите варианты, которые вы хотите сгенерировать, используя опцию variants:

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

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

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

Если вам нужно только указать варианты и не нужно отказываться от префикса по умолчанию или важных параметров, вы также можете напрямую передать массив вариантов в качестве второго параметра:

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

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

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

Если вы хотите, чтобы пользователь предоставил сами варианты в разделе variants в своем файле tailwind.config.js, вы можете использовать функцию 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 позволяет вам регистрировать новые стили в слое components Tailwind.

Используйте его для добавления более самоуверенных и сложных классов, таких как кнопки, элементы управления формы, предупреждения и т. д.; своего рода предварительно созданные компоненты, которые вы часто видите в других фреймворках, которые вам может потребоваться переопределить с помощью служебных классов.

Чтобы добавить новые стили компонентов из плагина, вызовите 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)
    })
  ]
}

Префикс и важные настройки

По умолчанию классы компонентов автоматически учитывают предпочтения пользователя 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:

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

Чтобы отказаться от префикса, передайте объект параметров в качестве второго параметра в addComponents:

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

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

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

Варианты

Чтобы сгенерировать отзывчивые, наведение, фокус, активные или другие варианты ваших компонентов, укажите варианты, которые вы хотите сгенерировать, используя опцию variants:

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

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

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

Если вам нужно только указать варианты и не нужно отказываться от префикса по умолчанию или важных параметров, вы также можете напрямую передать массив вариантов в качестве второго параметра:

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

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

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

Если вы хотите, чтобы пользователь предоставил сами варианты в разделе variants в своем файле tailwind.config.js, вы можете использовать функцию 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 позволяет вам регистрировать новые стили в слое base Tailwind.

Используйте его, чтобы добавить такие вещи, как базовые стили типографики, самоуверенные глобальные сбросы или правила @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 есть правила относительно символов, с которых имя класса может начинаться (класс не может начинаться с числа, но может содержать его), рекомендуется экранировать полное имя класса (а не только имя пользователя -предусмотренная часть), или вы можете получить ненужные escape-последовательности:

// Будет без надобности экранировать `1`
`.rotate-${e('1/4')}`
// => '.rotate-\31 \/4'

// Не будет экранировать `1`, потому что это не первый символ
`.${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,
      ])
    })
  ]
}

Если вы хотите сослаться на конфигурацию variants пользователя, рекомендуется использовать функцию variants() вместо функции config.

Не используйте функцию конфигурации для поиска вариантов

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

Вместо этого используйте функцию вариантов

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 в списке плагинов, указав свою конфигурацию с помощью ключа gradients как в theme и variants:

// 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 по умолчанию для Вашего плагина, передайте второй аргумент функции plugin Tailwind, который включает Ваши значения по умолчанию:

// ./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 plugin, за исключением того, что каждый аргумент должен быть функцией, которая принимает options пользователя и возвращает значение, которое вы обычно передали бы с помощью обычного 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'],
    }
  }
})

Пользователь будет вызывать ваш плагин, передавая свои параметры при регистрации его в своей конфигурации plugins:

// 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 и будут автоматически переведены в тире:

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, focus, active и т. д.

Чтобы добавить новый вариант, вызовите функцию 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, вспомогательная функция для упрощения добавления основных вариантов
  • separator, настроенный пользователем строка-разделитель
  • container, PostCSS Container, содержащий все правила, к которым применяется вариант, для создания сложных вариантов.

Простые варианты

Если вы хотите добавить простой вариант, в котором нужно только изменить селектор, используйте помощник modifySelectors.

Хелпер modifySelectors принимает функцию, которая получает объект, который можно деструктурировать на следующие части:

  • selector, полный немодифицированный селектор для текущего правила
  • className, имя класса текущего правила с удаленной начальной точкой

Функция, которую вы передаете в 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-правило), вам нужно будет использовать экземпляр 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
          })
        })
      })
    })
  ]
}

Этот плагин принимает все правила внутри контейнера, помещает их в at-правило @supports (display: grid) и добавляет к каждому правилу префикс 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');
  }
}