概要

プラグインを使用すると、CSSではなくJavaScriptを使用して、ユーザーのスタイルシートに挿入するための新しいスタイルをTailwindに登録できます。

最初のプラグインを使い始めるには、Tailwindのplugin関数をtailwindcss/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プラグインは、MarkdownやCMSデータベースなどのソースから取得したコンテンツブロックに適切なタイポグラフィスタイルをすばやく追加するために使用できる、一連のproseクラスを追加します。

<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プラグインは、ビューポートではなく、@containerでマークされた親の寸法に基づいて要素のスタイルを設定できる@{size}バリアント(@sm@mdなど)を追加します。

<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構文のリファレンスを参照してください。

動的ユーティリティ

ユーザーのtheme設定で定義された値にマップするユーティリティを登録するには、matchUtilities関数を使用します。

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>

プレフィックスとimportant

デフォルトでは、プラグインユーティリティはユーザーの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レイヤーに新しいスタイルを登録できます。

ボタン、フォームコントロール、アラートなど、より主観的で複雑なクラスを追加するために使用します。他のフレームワークでよく見られる、ユーティリティクラスで上書きする必要があるような、事前に構築されたコンポーネントです。

プラグインから新しいコンポーネントスタイルを追加するには、CSS-in-JS構文を使用してスタイルを渡してaddComponentsを呼び出します。

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ルールを追加するために使用します。

プラグインから新しいベーススタイルを追加するには、CSS-in-JS構文を使用してスタイルを渡してaddBaseを呼び出します。

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のようなベアメタセレクターを対象とすることを目的としているため、ユーザーのprefixまたはimportant設定を尊重しません。


バリアントの追加

addVariant関数とmatchVariant関数は、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>

動的バリアント

組み込みのsupports-*data-*aria-*バリアントのような、パラメーター化された新しいバリアントを登録するには、matchVariant関数を使用します。

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クラスが最終セレクターに1回だけ表示されるようにします。

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は通常のpluginAPIに似ていますが、各引数はユーザーの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ライブラリで認識できるのと同じ構文を使用し、内部的には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)': {
      // ...
    }
  },
])