Обзор

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

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

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

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

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

  • 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, которые можно использовать для быстрого добавления разумных типографских стилей к блокам контента, которые поступают из таких источников, как маркдаун или база данных 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" />

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

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

Плагин @tailwindcss/aspect-ratio является альтернативой встроенной поддержке aspect-ratio, которая работает в старых браузерах, и добавляет классы aspect-w-* и aspect-h-*, которые можно комбинировать для присвойте элементу фиксированное соотношение сторон.

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

Подробнее о плагине контейнерных запросов →


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

Функции addUtilities и matchUtilities позволяют вам регистрировать новые стили в макете утилит 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>

Приставка и важно

По умолчанию утилиты плагина автоматически учитывают предпочтения пользователя prefix и important.

Это означает, что с учетом данной конфигурации 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 позволяет вам регистрировать новые стили в слое components Tailwind.

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

Чтобы добавить новые стили компонентов из плагина, вызовите 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, только если они действительно используются в проекте.

Префикс и important

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

Поскольку базовые стили предназначены для простых селекторов, таких как div или h1, они не принимают во внимание пользовательскую конфигурацию prefix или important.


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

Функции addVariant и matchVariant позволяют вам регистрировать свои собственные модификаторы, которые можно использовать так же, как и встроенные варианты, такие как hover, focus или supports.

Статические варианты

Используйте функцию 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-* 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, также поддерживают произвольные значения с использованием обозначения квадратных скобок:

<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 с parent и sibling.

Чтобы поддерживать версии 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 ~ &')
      })
    ]
  }

Расширение конфигурации

Плагины могут объединять свой собственный набор значений конфигурации с пользовательской конфигурацией tailwind.config.js, предоставляя объект в качестве второго аргумента функции 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',
    }
  }
})

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


Варианты экспонирования

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

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