cubenoy22.com

【翻訳】tailwindcss.com - Core Concepts

この記事は Qiita のミラーです。リンクは こちら
Cover Image for 【翻訳】tailwindcss.com - Core Concepts

tailwindcss について興味を持ち理解を深めたいと考えたため翻訳。

ユーティリティファースト

https://tailwindcss.com/docs/utility-first

従来 Web 上でスタイルする必要がある場合はCSSを書く。

(一応コードを引用しますがオリジナルの方はプレビュー付きなので併読を推奨します)

{quote} :x: 独自のデザインに独自のCSSが必要となる従来のアプローチを使用してはいけない{quote}

<div class="chat-notification">
  <div class="chat-notification-logo-wrapper">
    <img class="chat-notification-logo" src="/img/logo.svg" alt="ChitChat Logo">
  </div>
  <div class="chat-notification-content">
    <h4 class="chat-notification-title">ChitChat</h4>
    <p class="chat-notification-message">You have a new message!</p>
  </div>
</div>

<style>
  .chat-notification {
    display: flex;
    max-width: 24rem;
    margin: 0 auto;
    padding: 1.5rem;
    border-radius: 0.5rem;
    background-color: #fff;
    box-shadow: 0 20px 25px -5px rgba(0, 0, 0, 0.1), 0 10px 10px -5px rgba(0, 0, 0, 0.04);
  }
  .chat-notification-logo-wrapper {
    flex-shrink: 0;
  }
  .chat-notification-logo {
    height: 3rem;
    width: 3rem;
  }
  .chat-notification-content {
    margin-left: 1.5rem;
    padding-top: 0.25rem;
  }
  .chat-notification-title {
    color: #1a202c;
    font-size: 1.25rem;
    line-height: 1.25;
  }
  .chat-notification-message {
    color: #718096;
    font-size: 1rem;
    line-height: 1.5;
  }
</style>

Tailwind では、既存のクラスをHTMLに直接適用することで要素のスタイリングを行う。

:o: CSSを書かずユーティリティクラスを使用して独自のデザインを実現する

<div class="max-w-sm mx-auto flex p-6 bg-white rounded-lg shadow-xl">
  <div class="flex-shrink-0">
    <img class="h-12 w-12" src="/img/logo.svg" alt="ChitChat Logo">
  </div>
  <div class="ml-6 pt-1">
    <h4 class="text-xl text-gray-900 leading-tight">ChitChat</h4>
    <p class="text-base text-gray-600 leading-normal">You have a new message!</p>
  </div>
</div>

上記例では

  • Tailwind の flexboxpadding ユーティリティ ( flex , flex-shrink-0 , p-6 ) を使用してカードレイアウト全体を制御
  • max-widthmargin ユーティリティ ( max-w-smmx-auto ) によってカード幅を制限し横方向の中央揃えに
  • 背景色, 角丸度合い, そして box-shadow ユーティリティ ( bg-white, rounded-lg, shadow-xl ) によってカードの外観をスタイリング
  • 横幅高さ ユーティリティ ( w-12h-12 ) によるロゴ画像のサイズ指定
  • マージンパディング ユーティリティ ( ml-6pt-1 ) によるカードのテキストの位置調整
  • フォントサイズ文字色line-height ユーティリティ ( text-xl, text-gray-900, leading-tight など) によるカードのテキストのスタイリング

これらにより CSS を1行も書くことなく独自のコンポーネントのデザインを完全に実装することを可能としている。

「これは酷い、なんてこった!」と思われたかもしれないがその気持ちはわかるし、その通り受け入れがたいだろう。だが瞬間的に良し悪しを判断するのは早計である、 まずは実際に試してみてほしい

この方法で実際に何か構築するといくつか重要な利点があることにすぐ気がつくはずだ:

  • クラスの名前を考える労力が0である ... なにかスタイリングするためだけに sidebar-inner-wrapper のようなクラス名をわざわざ追加する必要はないし、ただの flex コンテナに完璧な抽象名をつけようと悩む必要もない
  • CSSの肥大化を阻止できる ... 従来の手法では新機能を追加する毎にCSSファイルが巨大化してしまうが、ユーティリティならば全て再利用可能なので、新しくCSSを書くことは稀になる
  • より安心して変更できる ... CSSはグローバルであるため、修正を加えた時に予期せぬ変更をしてしまっていても気づくことができない、HTML内のクラス(属性)ならローカルなので、うっかり他へ影響を与えていないか心配せずに変更することが可能である

インラインスタイル(style属性)を使用しない理由

「これってただのインラインスタイルではないのか?」と言う疑問があるかもしれない。要素のクラス名を決めてからそのクラスを使うのではなく、スタイルを要素に直接適用している点ではそうともいえよう。

しかしユーティリティクラスを使用することでインラインスタイルに対していくつかの重要な長所がある:

  • 制約ありのデザイン ... インラインスタイルを使用すると全ての値はマジックナンバーになってしまう。ユーティリティならあらかじめ用意されている デザインテーマ からスタイルを選択するので、視覚的に一貫性を持ったUIを構築することがはるかに容易となる
  • レスポンシブデザイン ... インラインスタイルではメディアクエリは使用できないが、 Tailwind の レスポンシブデザイン なら完全対応したUIを容易に構築できる
  • 擬似クラス ... インラインスタイルではホバーやフォーカスといった状態を指定できないが、Tailwindの 擬似クラスバリアント ならユーティリティクラスを使用して状態に応じたスタイリングを簡単に構築できる

次に示すコンポーネントはフルレスポンシブかつホバーに対応したスタイルのボタンを内包しており、ユーティリティクラスだけで構築されている:

<div class="max-w-sm mx-auto bg-white shadow-lg rounded-lg overflow-hidden">
  <div class="sm:flex sm:items-center px-6 py-4">
    <img class="block mx-auto sm:mx-0 sm:flex-shrink-0 h-16 sm:h-24 rounded-full" src="/img/erin-lindford.jpg" alt="Woman's Face">
    <div class="mt-4 sm:mt-0 sm:ml-4 text-center sm:text-left">
      <p class="text-xl leading-tight">Erin Lindford</p>
      <p class="text-sm leading-tight text-gray-600">Product Engineer</p>
      <div class="mt-4">
        <button class="text-purple-500 hover:text-white hover:bg-purple-500 border border-purple-500 text-xs font-semibold rounded-full px-4 py-1 leading-normal">Message</button>
      </div>
    </div>
  </div>
</div>

保守性に対する懸念

ユーティリティファーストの手法で一番の懸念事項はユーティリティの組み合わせを毎回記述することであろう。

これはコンポーネントを部分テンプレート(template partials)かJavaScriptの コンポーネントとして抽出 するか、 Tailwind の @apply 機能を利用しユーティリティの組み合わせた抽象クラスを作成することで簡単に解決できる。

<!-- Using utilities -->
<button class="bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded">
  Button
</button>

<!-- Extracting classes using @apply -->
<button class="btn btn-blue">
  Button
</button>

<style>
  .btn {
    @apply font-bold py-2 px-4 rounded;
  }
  .btn-blue {
    @apply bg-blue-500 text-white;
  }
  .btn-blue:hover {
    @apply bg-blue-700;
  }
</style>

他にも、HTMLはCSSよりも保守が非常に容易であるということからユーティリティファーストのコードの保守は巨大なCSSの塊を保守するよりとても簡単であることがわかる。 GitHub や Heroku、Kickstarter、Twitch、Segment といった大企業でもこのアプローチを使うことで大きく成功している。

この手法に関する外部の情報をここに示しておく:

より詳しくは John Polacek が整理した The Case for Atomic/Utility-First CSS を確認されたい。

レスポンシブデザイン

Tailwind の全てのユーティリティクラスは異なるブレークポイントに対して条件的に適用が可能なため、HTMLの編集に集中したまま複雑なレスポンシブUIを構築できる。

デフォルトでは一般的な端末の解像度を想定した4つのブレークポイントを用意している:

/* 小 - Small (sm) */
@media (min-width: 640px) { /* ... */ }

/* 中 - Medium (md) */
@media (min-width: 768px) { /* ... */ }

/* 大 - Large (lg) */
@media (min-width: 1024px) { /* ... */ }

/* 特大 - Extra Large (xl) */
@media (min-width: 1280px) { /* ... */ }

特定のブレークポイントでのみ有効なユーティリティクラスを追加するには、クラス名の前にブレークポイント名と : をプリフィクスとしてつけるだけである:

<!-- デフォルトで横幅16, 中画面だと32, 大画面であれば48 -->
<img class="w-16 md:w-32 lg:w-48" src="...">

これは フレームワーク内のすべてのユーティリティクラス で有効であるため、文字の間隔やカーソルのスタイルなどであっても特定のブレークポイントによって変更することが可能である。

小さい画面では縦並び(stack)、より大きい画面では横並びとなるマーケティングページのコンポーネントの例を示す:

<div class="md:flex">
  <div class="md:flex-shrink-0">
    <img class="rounded-lg md:w-56" src="https://images.unsplash.com/photo-1556740738-b6a63e27c4df?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=2550&q=80" alt="Woman paying for a purchase">
  </div>
  <div class="mt-4 md:mt-0 md:ml-6">
    <div class="uppercase tracking-wide text-sm text-indigo-600 font-bold">Marketing</div>
    <a href="#" class="block mt-1 text-lg leading-tight font-semibold text-gray-900 hover:underline">Finding customers for your new business</a>
    <p class="mt-2 text-gray-600">Getting a new business off the ground is a lot of hard work. Here are five ideas you can use to find your first customers.</p>
  </div>
</div>

これはこのような仕組みとなっている:

  • デフォルトでは外側のdivは display: block だが、 md:flex を追加することで中画面以上では display: flex となる
  • flex のコンテナが親の時は画像が縮まないようにしたいので md:flex-shrink-0 を追加し、中画面以上では縮小されないようにしている、厳密には小さい画面ではなにも起きないので flex-shrink-0 を使用することも可能ではあるが、 md の画面でしか意味がないのでクラス名で明示しておくほうが良い
  • 小さい画面では画像はデフォルトで自動的に横幅いっぱいで表示され、中画面以上では md:w-56 を指定して横幅を固定にしている
  • 小さい画面ではコンテンツの部分で mt-4 を追加して画像とコンテンツの間に若干のマージンを追加している、このマージンは横並びのレイアウトでは不要なため、 md:mt-0 を使用しこのマージンを打ち消しつつ、代わりに md:ml-6 も追加することで左マージンを若干追加している

この例では一つのブレークポイントしか使用していないが、 sm, lg, xl といったプリフィクスも同様に使うことでこのコンポーネントを他のサイズ向けにカスタマイズすることは容易である。

モバイルファースト

デフォルトでは Tailwind はモバイルファーストのブレークポイント体系を使用する。これは Bootstrap や Foundation で使われているものと似ている。

upppercase のようなプリフィクスなしのユーティリティは全ての画面サイズで有効なのに対し、 md:uppercase のようなプレフィクスありのユーティリティは指定されたブレークポイント 以上 でのみ有効ということになる。

ブレークポイント毎に背景色が変わる例をここに示す:

<div class="bg-red-500 sm:bg-green-500 md:bg-blue-500 lg:bg-pink-500 xl:bg-teal-500"></div>

(原文ではウィンドウ幅を変えることなくボタンだけで各レスポンシブ幅のレイアウトを確認するウィジェットについての説明が記述されているがここでは引用不可のため省略)

モバイル画面をターゲットにする

モバイル向けに何かスタイルを設定する場合、 sm: プレフィクス付きではなくプリフィクスなしを使う必要があるという点について驚かれるかもしれない。
sm: プリフィクスを「小さい画面のとき」として考えず、「小さなブレークポイントのとき」と考えてほしい。

:x: sm: をモバイル端末用として使ってはいけない

<!-- モバイルが対象ではなく画面幅が640px以上の時だけテキストがセンタリングされてしまう -->
<div class="sm:text-center"></div>

:o: モバイル向けはプリフィクスなしのユーティリティクラスを使い、より大きいブレークポイントで上書きする

<!-- モバイルではセンタリング、画面幅が 640px 以上なら左寄せ -->
<div class="text-center sm:text-left"></div>

以上から多くの場合、最初にモバイル用のデザインのレイアウトから実装し、その後 sm 画面用の変更を適用し、 md 画面などの変更に着手するのがよいはずだ。

1つのブレークポイントを狙い撃ちする

Tailwind のブレークポイントは min-width のみ指定しており max-width は指定していない。これは小さなブレークポイントに追加したユーティリティはより大きいブレークポイントにも適用されることを意味する。

一つのブレークポイントだけにユーティリティを適用したい場合はそれを打ち消す別のユーティリティをより大きいサイズに追加することで 取り消す ことが可能だ。

ここに md のブレークポイントの時に背景色を赤にし、他のブレークポイントではティール(色の名前)とする例を示す:

<div class="bg-teal-500 md:bg-red-500 lg:bg-teal-500"></div>

sm ブレークポイントや xl ブレークポイントに対して指定して いない ことに注目してほしい。ユーティリティクラスの効果を発揮する始点のみ指定するだけでよいということになる。

ブレークポイントのカスタマイズ

tailwind.config.js ファイルでブレークポイントを自由にカスタマイズすることが可能である:

// tailwind.config.js
module.exports = {
  theme: {
    screens: {
      'tablet': '640px',
      // => @media (min-width: 640px) { ... }

      'laptop': '1024px',
      // => @media (min-width: 1024px) { ... }

      'desktop': '1280px',
      // => @media (min-width: 1280px) { ... }
    },
  }
}

詳しくは ブレークポイントをカスタマイズする を参照されたい。

擬似クラスバリアント

前出の レスポンシブデザイン のように、ホバーやフォーカスといった要素のスタイリングも適切な擬似クラスのプリフィクスをつけることで実現が可能である。

<form>
  <input class="bg-gray-200 hover:bg-white hover:border-gray-300 focus:outline-none focus:bg-white focus:shadow-outline focus:border-gray-300 ...">
  <button class="bg-teal-500 hover:bg-teal-600 focus:outline-none focus:shadow-outline ...">
    Sign Up
  </button>
</form>

ファイルサイズについて熟慮した結果、 デフォルトで全ての擬似クラスバリアントがすべてのユーティリティで有効になっていない 点について注意が必要である。なにもせずとも(out-of-the-box)よく使われるであろう組み合わせでは有効になるよう最善を尽くしている。

デフォルトで有効になっているバリアントの完全なリストについては リファレンス表 を参照されたい。

もし Tailwind で未サポートの擬似クラスを使う必要があれば、 バリアントのプラグインを書く ことで対応バリアントを増やすことが可能である。

Hover

hover: プリフィクスを追加するだけでユーティリティを制限できる:

<button class="bg-transparent hover:bg-blue-500 text-blue-700 hover:text-white...">
  Hover me
</button>

hover バリアントを有効にするかどうかは tailwind.config.js ファイルの variants セクションで制御が可能である:

// tailwind.config.js
module.exports = {
  // ...
  variants: {
    backgroundColor: ['responsive', 'hover', 'focus'],
  },
}

Focus

focus: プリフィクスを追加するだけでユーティリティを制限できる:

<input class="bg-gray-200 focus:bg-white border-transparent focus:border-blue-400 ..." placeholder="Focus me">

focus バリアントを有効にするかどうかは hover 同様 tailwind.config.js ファイルの variants セクションで制御が可能である (記述例は繰り返しになるので省略)

Active

<button class="bg-blue-500 active:bg-blue-700 text-white...">
  Click me
</button>

Group-hover

特定の親要素上でホバーする時に子要素をスタイルする必要があるのであれば、 .group クラスを親要素に付与し group-hover: プリフィクスを子要素のユーティリティクラスに追加する。

<div class="group bg-white hover:bg-blue-500 ...">
  <p class="text-gray-900 group-hover:text-white ...">New Project</p>
  <p class="text-gray-700 group-hover:text-white ...">Create a new project from a variety of starting templates.</p>
</div>

Group-focus (v1.3.0+)

group-focus バリアントはフォーカス以外は group-hover と同様に機能する

Focus-within

:warning: この機能はIEまたはEdge < 79 ではサポートされない

focus-within: プリフィクスを付与すれば子要素にフォーカスした時のみユーティリティを適用できる

<form class="border-b-2 border-gray-400 focus-within:border-teal-500 ...">
  <input class="..." placeholder="Jane Doe" ...>
  <button class="...">
    Sign Up
  </button>
</form>

Focus-visible (v1.5.0+)

:warning: この機能は現時点ではブラウザを十分にサポートするためにポリフィルが必要である

focus-visible: プリフィクスを付与することで要素にフォーカスしつつユーザーがキーボードを使用している場合のみユーティリティクラスを有効にできる:

<ul class="flex space-x-8">
  <li>
    <a class="focus:outline-none focus:underline ..." href="#">
      Underlined on focus
    </a>
  </li>
  <li>
    <a class="focus:outline-none focus-visible:underline ..." href="#">
      Underlined on focus-visible
    </a>
  </li>
</ul>

(左のリンクはクリックすると下線がつくが右のリンクはつかない、クリックしてからキーを押下したりあるいはタブキーでフォーカスを当てると下線が出る)

Firefoxのみがサポートしているため、十分にブラウザをサポートするためには focus-visible のJSポリフィルfocus-visible のPostCSSポリフィル の両方がインストールされ設定されている必要がある。PostCSSのプラグインは一覧で Tailwind より 後に 追加されるようにしてほしい:

// postcss.config.js
module.exports = {
  plugins: {
    tailwindcss: {},
    'postcss-focus-visible': {},
    autoprefixer: {}
  }
}

Motion-safe (v1.6.0+)

motion-safe: プリフィクスを付与することで prefers-reduces-motion メディアクエリが no-preference の時のみユーティリティクラスが適用されるようにできる。たとえば下記のボタンはユーザーがシステム(ブラウザ)の設定で余計な動きを減らす("Reduce motion")設定を有効にしていない時だけアニメーションする:

<button class="transform motion-safe:hover:-translate-y-1 motion-safe:hover:scale-110 transition ease-in-out duration-300 ...">
  Hover
</button>

他の多数のバリアントとは異なり motion-safe はレスポンシブ用のバリアントや hover といった他のバリアントを組み合わせて使用することができる:

<div class="sm:motion-safe:hover:animate-spin">
  <!-- ... -->
</div>

Motion-reduce (v1.6.0+)

motion-reduce: プリフィクスを付与することで prefers-reduced-motion メディアクエリが reduce の時のみユーティリティが適用されるようにできる。例えば下記のボタンはデフォルトでホバー時にアニメーションするが、ユーザーが余計な動きを減らす("Reduce motion")設定を有効にしている場合は無効化される:

<button class="transform motion-reduce:transform-none hover:-translate-y-1 hover:scale-110 transition ease-in-out duration-300 ...">
  Hover
</button>

この motion-reducemotion-safe 同様、レスポンシブ用 / hover といった他のバリアントと組み合わせが可能。

Disabled (v1.1.0+)

disabled: プリフィクスを付与すれば要素が無効化(非活性化)しているときにユーティリティクラスが適用されるようにできる:

<button class="disabled:opacity-75 bg-blue-500...">
  Submit
</button>

<button disabled class="disabled:opacity-75 bg-blue-500...">
  Submit
</button>

Visited (v1.1.0+)

visited: プリフィクスを付与すれば訪問済みリンクに対してのみユーティリティクラスを適用できる:

<a href="#" class="text-blue-600 visited:text-purple-600 ...">Link</a>

Checked (v1.5.0+)

checked: プリフィクスを付与すればchecked状態のラジオボタン・チェックボックスに対してのみユーティリティクラスを適用できる

<input type="radio" class="appearance-none checked:bg-gray-900 checked:border-transparent ...">

First-child (v1.1.0+)

first: プリフィクスを付与すればその要素が親要素の最初の要素(first-child)のときだけユーティリティクラスが適用されるようにできる。ループなどで要素が複数作成される場合などで特に効果的である:

<div class="border rounded">
  <div v-for="item in items" class="border-t first:border-t-0">
    {{ item }}
  </div>
</div>

(3行のリストで各行のトップに境界線を入れつつ外側を枠線で囲っているデモ、first で最初の要素だけ境界線をなくすことで一番上の境界線が二重にならないようにしている)

first: プリフィクスは子要素のユーティリティクラスに対して追加するのであって、親要素ではないので注意。

Last-child (v1.1.0+)

last: プリフィクスを付与すればその要素が親要素の最後の要素(last-child)の時だけユーティリティクラスが適用されるようにできる。こちらも first: 同様ループで効果的である。

Odd-child (v1.1.0+)

odd: プリフィクスを付与すればその要素が親要素の奇数番目(odd-child)にある場合のみユーティリティクラスを適用できる。こちらも first: 同様ループで効果的である。

<div class="border rounded">
  <div v-for="item in items" class="bg-white odd:bg-gray-200">
    {{ item }}
  </div>
</div>

Even-child (v1.1.0+)

even: プリフィクスは odd: の偶数版。

レスポンシブ用のプリフィクスと組み合わせる

擬似クラスバリアントはレスポンシブでもあるため、例えばブレークポイント別で要素のホバーのスタイルを切り替えるといったことが可能である。

特定のブレークポイントに擬似クラスバリアントを適用するには、まずレスポンシブ用のプリフィクスを書いて、その後ろに擬似クラスのプリフィクスを記述する:

<button class="bg-orange-500 hover:bg-orange-600 sm:bg-green-500 sm:hover:bg-green-600 md:bg-red-500 md:hover:bg-red-600 lg:bg-indigo-500 lg:hover:bg-indigo-600 xl:bg-pink-500 xl:hover:bg-pink-600 ">
  Button
</button>

独自ユーティリティ用のバリアント生成

CSS 内で @variants ディレクティブでラップすることによって自作ユーティリティに対しても擬似クラスバリアントは生成可能である:

/* ソース: */
@variants group-hover, hover, focus {
  .banana {
    color: yellow;
  }
}

/* 生成結果: */
.banana {
  color: yellow;
}
.group:hover .group-hover\:banana {
  color: yellow;
}
.hover\:banana:hover {
  color: yellow;
}
.focus\:banana:focus {
  color: yellow;
}

より詳しい情報については @variants を参照されたい。

独自バリアントの作成

Tailwind にデフォルトで含まれていない擬似クラス用のバリアントは独自バリアント用のプラグインを書くことで作成可能である。

ここに disabled 擬似クラスバリアントをサポートするための簡単なプラグインの例を示す:

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

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

詳しくは variant plugin documentation を参照されたい。

デフォルトバリアントのリファレンス

ファイルサイズについて検討した結果、デフォルトで全ての擬似クラスバリアントを組み込んでいない。

プロジェクト毎にどのバリアントを有効化するか設定するには configuring variants documentation を参照されたい。

// Default configuration
module.exports = {
  // ...
  variants: {
    accessibility: ['responsive', 'focus'],
    alignContent: ['responsive'],
    alignItems: ['responsive'],
    alignSelf: ['responsive'],
    appearance: ['responsive'],
    backgroundAttachment: ['responsive'],
    backgroundColor: ['responsive', 'hover', 'focus'],
    backgroundOpacity: ['responsive', 'hover', 'focus'],
    backgroundPosition: ['responsive'],
    backgroundRepeat: ['responsive'],
    backgroundSize: ['responsive'],
    borderCollapse: ['responsive'],
    borderColor: ['responsive', 'hover', 'focus'],
    borderOpacity: ['responsive', 'hover', 'focus'],
    borderRadius: ['responsive'],
    borderStyle: ['responsive'],
    borderWidth: ['responsive'],
    boxShadow: ['responsive', 'hover', 'focus'],
    boxSizing: ['responsive'],
    clear: ['responsive'],
    cursor: ['responsive'],
    display: ['responsive'],
    divideColor: ['responsive'],
    divideOpacity: ['responsive'],
    divideWidth: ['responsive'],
    fill: ['responsive'],
    flex: ['responsive'],
    flexDirection: ['responsive'],
    flexGrow: ['responsive'],
    flexShrink: ['responsive'],
    flexWrap: ['responsive'],
    float: ['responsive'],
    fontFamily: ['responsive'],
    fontSize: ['responsive'],
    fontSmoothing: ['responsive'],
    fontStyle: ['responsive'],
    fontWeight: ['responsive', 'hover', 'focus'],
    gap: ['responsive'],
    gridAutoFlow: ['responsive'],
    gridColumn: ['responsive'],
    gridColumnEnd: ['responsive'],
    gridColumnStart: ['responsive'],
    gridRow: ['responsive'],
    gridRowEnd: ['responsive'],
    gridRowStart: ['responsive'],
    gridTemplateColumns: ['responsive'],
    gridTemplateRows: ['responsive'],
    height: ['responsive'],
    inset: ['responsive'],
    justifyContent: ['responsive'],
    letterSpacing: ['responsive'],
    lineHeight: ['responsive'],
    listStylePosition: ['responsive'],
    listStyleType: ['responsive'],
    margin: ['responsive'],
    maxHeight: ['responsive'],
    maxWidth: ['responsive'],
    minHeight: ['responsive'],
    minWidth: ['responsive'],
    objectFit: ['responsive'],
    objectPosition: ['responsive'],
    opacity: ['responsive', 'hover', 'focus'],
    order: ['responsive'],
    outline: ['responsive', 'focus'],
    overflow: ['responsive'],
    padding: ['responsive'],
    placeholderColor: ['responsive', 'focus'],
    placeholderOpacity: ['responsive', 'focus'],
    pointerEvents: ['responsive'],
    position: ['responsive'],
    resize: ['responsive'],
    rotate: ['responsive', 'hover', 'focus'],
    scale: ['responsive', 'hover', 'focus'],
    skew: ['responsive', 'hover', 'focus'],
    space: ['responsive'],
    stroke: ['responsive'],
    strokeWidth: ['responsive'],
    tableLayout: ['responsive'],
    textAlign: ['responsive'],
    textColor: ['responsive', 'hover', 'focus'],
    textDecoration: ['responsive', 'hover', 'focus'],
    textOpacity: ['responsive', 'hover', 'focus'],
    textTransform: ['responsive'],
    transform: ['responsive'],
    transformOrigin: ['responsive'],
    transitionDelay: ['responsive'],
    transitionDuration: ['responsive'],
    transitionProperty: ['responsive'],
    transitionTimingFunction: ['responsive'],
    translate: ['responsive', 'hover', 'focus'],
    userSelect: ['responsive'],
    verticalAlign: ['responsive'],
    visibility: ['responsive'],
    whitespace: ['responsive'],
    width: ['responsive'],
    wordBreak: ['responsive'],
    zIndex: ['responsive'],
  }
}

基底スタイルの追加

https://tailwindcss.com/docs/adding-base-styles

基底(あるいはグローバル)のスタイルは <a> タグや見出しなどのHTML要素にデフォルト値をセットしたり、流行りの box-sizing のリセット のような個人意見的なリセット (opinionated reset) を適用するのに有用な、スタイルシートの先頭に記すスタイルのことである。

Tailwind では normalize.css に個人意見的なスタイルを追加した軽量な プレフライト という、すぐ使える便利な基底スタイルのセットを用意している。

プレフライトは大多数のプロジェクトにおいて良い開始地点となるが、独自の基底スタイルを追加したい場合は慣用的に行うべきいくつかの推奨事項をここに示す。

HTMLでクラスを使う

htmlbody 要素へグローバルなスタイルを適用したい場合はCSSを新規に書くのではなくHTML内の要素へ既存のクラスを追記する方法を検討してみてほしい:

<!doctype html>
<html lang="en" class="text-gray-900 antialiased leading-tight">
 <!-- ... -->
 <body class="min-h-screen bg-gray-100">
   <!-- ... -->
 </body>
</html>

CSSを使う

特定の要素へ基底スタイルを適用したい場合に最も簡単な方法はずばりCSSを書くことだ。 @tailwind base の後に任意の基底スタイルを定義し、一部の問題を避けるため @tailwind components で閉じてほしい:

@tailwind base;

h1 {
 @apply text-2xl;
}
h2 {
 @apply text-xl;
}
h3 {
 @apply text-lg;
}
a {
 @apply text-blue-600 underline;
}

@tailwind components;

@tailwind utilities;

@applytheme() を使用してスタイルを定義し、うっかりマジックナンバーを作ってしまったりデザインからの逸脱を避けるのは良い心がけであろう。

@font-face 規約

同じ要領で使用しているカスタムフォントに対して @font-face 規約も追加できる:

@tailwind base;

@font-face {
  font-family: Proxima Nova;
  font-weight: 400;
  src: url(/fonts/proxima-nova/400-regular.woff) format("woff");
}
@font-face {
  font-family: Proxima Nova;
  font-weight: 500;
  src: url(/fonts/proxima-nova/500-medium.woff) format("woff");
}

@tailwind components;

@tailwind utilities;

プラグインを使う

addBase 関数を使った プラグインを書く ことでも基底スタイルを追加することが可能だ:

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

module.exports = {
  plugins: [
    plugin(function({ addBase, config }) {
      addBase({
        'h1': { fontSize: config('theme.fontSize.2xl') },
        'h2': { fontSize: config('theme.fontSize.xl') },
        'h3': { fontSize: config('theme.fontSize.lg') },
      })
    })
  ]
}

addBase を使用して追加したスタイルは自動的に @tailwind base スタイルの中に組み込まれる。

プラグインを使うタイミング

プラグインを書くよりかはCSSをプロジェクト内に書く方が一般的には簡単だ。ただし次のような場合はプラグインのほうがよいだろう:

  • 独自の基底スタイルを外部へ公開し他のユーザーが簡単に利用できるようにしたい場合
  • 社内の複数のプロジェクト間で基底スタイルを再利用し、CSSの依存ではなくJSの依存として共有したい場合

コンポーネントを抽出する

Tailwind では早い段階での抽象化を避け最初はユーティリティクラスのみを使用してデザインを実装する ユーティリティファースト なワークフローを奨励している。

<!-- ユーティリティクラスだけで実装したマーケティングのページ用のカードの例 -->
<div class="md:flex">
  <div class="md:flex-shrink-0">
    <img class="rounded-lg md:w-56" src="https://images.unsplash.com/photo-1556740738-b6a63e27c4df?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=448&q=80" alt="Woman paying for a purchase">
  </div>
  <div class="mt-4 md:mt-0 md:ml-6">
    <div class="uppercase tracking-wide text-sm text-indigo-600 font-bold">Marketing</div>
    <a href="#" class="block mt-1 text-lg leading-tight font-semibold text-gray-900 hover:underline">Finding customers for your new business</a>
    <p class="mt-2 text-gray-600">Getting a new business off the ground is a lot of hard work. Here are five ideas you can use to find your first customers.</p>
  </div>
</div>

しかしプロジェクトが大きくなるにつれ、あらゆるところで同じコンポーネントを作るためにユーティリティの組み合わせが繰り返されていることに気がつくであろう。これはボタンやフォーム要素、バッジといった小さいコンポーネントで顕著である。

<!-- ボタン毎にクラスを繰り返すのは辛い -->
<button class="bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded">
  Button
</button>

コンポーネントのインスタンス間でユーティリティの長い列を維持するのはすぐ保守の負担になりうるので、繰り返しがつらいと気がついたタイミングでコンポーネントの抽象化を行うとよい。

HTMLコンポーネントを抽出する

UIコンポーネントを定義するために必要な情報がCSSのみで完結することは極めて稀で、対となる重要なHTML構造が必要であろう。

:x: 複雑なコンポーネントを抽象化するためにCSSクラスに頼ってはいけない

<style>
  .vacation-card { /* ... */ }
  .vacation-card-info { /* ... */ }
  .vacation-card-eyebrow { /* ... */ }
  .vacation-card-title { /* ... */ }
  .vacation-card-price { /* ... */ }
</style>

<!-- 独自のCSSを使用しても、このHTML構造を複製する必要がある -->
<div class="vacation-card">
  <img class="vacation-card-image" src="..." alt="Beach in Cancun">
  <div class="vacation-card-info">
    <div>
      <div class="vacation-card-eyebrow">Private Villa</div>
      <div class="vacation-card-title">
        <a href="/vacations/cancun">Relaxing All-Inclusive Resort in Cancun</a>
      </div>
      <div class="vacation-card-price">$299 USD per night</div>
    </div>
  </div>
</div>

故に独自のCSSクラスを書くのではなくUIの再利用可能な部分を 部分テンプレートJavaScript コンポーネント に抽出する方がうまくいくことが少なくない。

ただ一つの情報源(single source of truth)となるテンプレートを作れば、同じクラスの並びを何度も複製して作ることによる保守負担を避けてユーティリティクラスを使い続けることが可能となる。

:o: 部分テンプレート/JavaScriptコンポーネントを作る

<!-- 使う側 -->
<VacationCard
  img="/img/cancun.jpg"
  imgAlt="Beach in Cancun"
  eyebrow="Private Villa"
  title="Relaxing All-Inclusive Resort in Cancun"
  pricing="$299 USD per night"
  url="/vacations/cancun"
/>

<!-- ./components/VacationCard.vue -->
<template>
  <div>
    <img class="rounded" :src="img" :alt="imgAlt">
    <div class="mt-2">
      <div>
        <div class="text-xs text-gray-600 uppercase font-bold">{{ eyebrow }}</div>
        <div class="font-bold text-gray-700 leading-snug">
          <a :href="url" class="hover:underline">{{ title }}</a>
        </div>
        <div class="mt-2 text-sm text-gray-600">{{ pricing }}</div>
      </div>
    </div>
  </div>
</template>

<script>
  export default {
    props: ['img', 'imgAlt', 'eyebrow', 'title', 'pricing', 'url']
  }
</script>

上記例では Vue を使用しているが、 ReactのコンポーネントERBのパーシャルBladeのコンポーネントTwigのinclude などでも同じようなアプローチが可能だ。

@apply でCSSコンポーネントを抽出する

ボタンやフォーム要素といった小さいコンポーネント用に部分テンプレートやJavaScriptコンポーネントを作ることはCSSクラスを書くのに比べて荷が重いと感じてしまうことがよくあるであろう。

このような場合、Tailwindの @apply ディレクティブを使えば共通のユーティリティの組み合わせをCSSコンポーネントクラスに抽出可能だ。

ここに @apply を使用して既存のユーティリティを作成した .btn-blue クラスを示す:

<button class="btn-blue">
  Button
</button>

<style>
.btn-blue {
  @apply bg-blue-500 text-white font-bold py-2 px-4 rounded;
}
.btn-blue:hover {
  @apply bg-blue-700;
}
</style>

hover:focus:{screen}: といったバリアントは @apply では使用できないので、代わりに擬似セレクタやメディアクエリと通常版のユーティリティクラスを組み合わせて適用してほしい。

このようなクラスは特定の問題を避けるため @tailwind components ディレクティブより後ろに追加されるべきである。

:x: CSSの末尾に独自コンポーネント用のクラスを追加してはいけない

@tailwind base;

@tailwind components;

@tailwind utilities;

.btn-blue {
  @apply bg-blue-500 text-white font-bold py-2 px-4 rounded;
}
.btn-blue:hover {
  @apply bg-blue-700;
}

:o: utlities の前に独自コンポーネント用のクラスを追加する

@tailwind base;

@tailwind components;

.btn-blue {
  @apply bg-blue-500 text-white font-bold py-2 px-4 rounded;
}
.btn-blue:hover {
  @apply bg-blue-700;
}

@tailwind utilities;

組み合わせ可能な状態を維持する

このような二つのボタンに対して

<button class="bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded">
  Button
</button>

<button class="bg-gray-400 hover:bg-gray-500 text-gray-800 font-bold py-2 px-4 rounded">
  Button
</button>

こんなコンポーネントクラスを実装したくなるかもしれない:

.btn-blue {
  @apply bg-blue-500 text-white font-bold py-2 px-4 rounded;
}
.btn-blue:hover {
  @apply bg-blue-700;
}

.btn-gray {
  @apply bg-gray-400 text-gray-800 font-bold py-2 px-4 rounded;
}
.btn-gray:hover {
  @apply bg-gray-500;
}

このアプローチには苦痛な重複が発生しうるという問題がある。

もしサイト上の全てのボタンのパディングやフォントの太さ、角丸具合を変えようとした場合、全部のボタンのクラスの書き換えを余儀なくさせられるだろう。

より良いアプローチとしては共通部分を別のクラスへ抽出することだ:

.btn {
  @apply font-bold py-2 px-4 rounded;
}

.btn-blue {
  @apply bg-blue-500 text-white;
}
.btn-blue:hover {
  @apply bg-blue-700;
}

.btn-gray {
  @apply bg-gray-400 text-gray-800;
}
.btn-gray:hover {
  @apply bg-gray-500;
}

この場合ボタンにスタイルを当てる必要がある時は常に2つのクラスを適用することとなる:

<button class="btn btn-blue">
  Button
</button>

<button class="btn btn-gray">
  Button
</button>

この変更により .btn クラスを編集するだけで共有されたスタイルの変更が容易となった。

また新しいコンポーネントクラスを作ったり共通スタイルを複製することなく、1度しか使わないボタンのスタイルを追加することも可能となる:

<button class="btn bg-green-500 hover:bg-green-400 text-white">
  Button
</button>

コンポーネントプラグインを書く

CSSファイルに直接コンポーネント用のクラスを書くのに加えて、プラグインを作れば Tailwind にコンポーネント用のクラスを追加することも可能だ:

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

この方法は Tailwind 用のコンポーネントをライブラリとして公開したり、複数のプロジェクト間でコンポーネントを共有しやすくするのに適している。

詳しくは component plugin documentation を参照されたい。

新しいユーティリティを追加する

https://tailwindcss.com/docs/adding-new-utilities

Tailwind ではすぐに使える広範囲をカバーしたユーティリティクラスのセットを提供するが、独自のクラスを追加しなければならない状況もあるだろう。

ここでは可能な限り簡単な方法で独自のユーティリティを追加するのに役立つベストプラクティクスをいくつか紹介したい。

CSSを使用する

Tailwind に独自のユーティリティクラスを追加する最も簡単な方法は、ずばりCSSを書くことだ。

:o: CSSファイルの末尾に独自のユーティリティを追加する

@tailwind base;
@tailwind components;
@tailwind utilities;

.rotate-0 {
  transform: rotate(0deg);
}
.rotate-90 {
  transform: rotate(90deg);
}
.rotate-180 {
  transform: rotate(180deg);
}
.rotate-270 {
  transform: rotate(270deg);
}

CSS内で定義する順番が重要だ、特定の問題を回避するためいつでもCSSの 末尾 にユーティリティを追加するようにしてほしい。

:x: CSSの先頭に追加してはいけない

/* ユーティリティクラスを先頭に書くと特定の問題が起きる可能性がある */
.rotate-0 {
  transform: rotate(0deg);
}
.rotate-90 {
  transform: rotate(90deg);
}
.rotate-180 {
  transform: rotate(180deg);
}
.rotate-270 {
  transform: rotate(270deg);
}

@tailwind base;
@tailwind components;
@tailwind utilities;

postcss-import や Less, Sass, Stylus などのプリプロセッサを使用している場合はファイルを分けてインポートする方法を検討してみてほしい:

/* postcss-import を使用している場合 */
@import "tailwindcss/base";
@import "tailwindcss/components";
@import "tailwindcss/utilities";
@import "./custom-utilities.css";

/* Sass か Less を使用している場合 */
@tailwind base;
@tailwind components;
@tailwind utilities;
@import "./custom-utilities";

レスポンシブバリアントを生成する

tailwind.config.js ファイルに定義したブレークポイントに基づいて独自ユーティリティクラスの レスポンシブバリアント を作成する場合、 @responsive ディレクティブ内でユーティリティをラップしてほしい:

@tailwind base;
@tailwind components;
@tailwind utilities;

@responsive {
  .rotate-0 {
    transform: rotate(0deg);
  }
  .rotate-90 {
    transform: rotate(90deg);
  }
  .rotate-180 {
    transform: rotate(180deg);
  }
  .rotate-270 {
    transform: rotate(270deg);
  }
}

Tailwind では独自のユーティリティクラス毎にプリフィクスがついたバージョンを自動的に生成するので、ブレークポイントに応じてスタイルを条件的に適用することが可能である:

<!-- デフォルトで180度回転させるが中画面以上では無効にする -->
<div class="rotate-180 md:rotate-0"></div>

さらに詳しい情報は レスポンシブデザイン を参照されたい。

擬似クラスバリアントを生成する

独自の 擬似クラスバリアント を作りたい場合は、 @variants ディレクティブでラップする:

@tailwind base;
@tailwind components;
@tailwind utilities;

@variants hover, focus {
  .rotate-0 {
    transform: rotate(0deg);
  }
  .rotate-90 {
    transform: rotate(90deg);
  }
  .rotate-180 {
    transform: rotate(180deg);
  }
  .rotate-270 {
    transform: rotate(270deg);
  }
}

Tailwind では独自のユーティリティクラス毎にプリフィクスがついたバージョンを自動的に生成するので、状態に応じてスタイルを条件的に適用することが可能である:

<div class="rotate-0 hover:rotate-90"></div>

擬似クラスバリアントは @variants ディレクティブ内で記述した順番と同じ順序で生成されるので、擬似クラスを別の擬似クラスより優先させたい場合は、必ず最後のほうに書くようにしてほしい:

/* フォーカスはホバーより優先される */
@variants hover, focus {
  .rotate-0 {
    transform: rotate(0deg);
  }
  /* ... */
}

/* ホバーはフォーカスより優先される */
@variants focus, hover {
  .rotate-0 {
    transform: rotate(0deg);
  }
  /* ... */
}

独自ユーティリティをレスポンシブかつ擬似クラスバリアント対応で生成したい時は @variants@responsive でラップしてほしい:

@tailwind base;
@tailwind components;
@tailwind utilities;

@responsive {
  @variants hover, focus {
    .rotate-0 {
      transform: rotate(0deg);
    }
    .rotate-90 {
      transform: rotate(90deg);
    }
    .rotate-180 {
      transform: rotate(180deg);
    }
    .rotate-270 {
      transform: rotate(270deg);
    }
  }
}

より詳しい情報については 擬似クラスバリアント を参照されたい。

プラグインを使う

CSSファイルへ直接ユーティリティクラスを記述する方法に加えて、プラグインを書くことで Tailwind にユーティリティクラスを追加することも可能である:

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

module.exports = {
  plugins: [
    plugin(function({ addUtilities }) {
      const newUtilities = {
        '.rotate-0': {
          transform: 'rotate(0deg)',
        },
        '.rotate-90': {
          transform: 'rotate(90deg)',
        },
        '.rotate-180': {
          transform: 'rotate(180deg)',
        },
        '.rotate-270': {
          transform: 'rotate(270deg)',
        },
      }

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

この方法は Tailwind 用のコンポーネントをライブラリとして公開したり、複数のプロジェクト間でコンポーネントを共有しやすくするのに適している。

詳しくは utility plugin documentation を参照されたい。

関数とディレクティブ

https://tailwindcss.com/docs/functions-and-directives

@tailwind

Tailwind の base, components, utilities そして screens の各スタイルをCSSに挿入するには @tailwind ディレクティブを使用する。

/**
 * Tailwind の基底スタイルとプラグインによって登録された追加の基底スタイルが挿入される
 */
@tailwind base;

/**
 * Tailwind のコンポーネント用のクラスとプラグインによって登録された追加のクラスが挿入される
 */
@tailwind components;

/**
 * Tailwind のユーティリティクラスとプラグインによって登録された追加のクラスが挿入される
 */
@tailwind utilities;

/**
 * 各ユーティリティクラスのレスポンシブの派生を挿入したい場所にこのディレクティブを書く
 * 
 * 省略した場合、デフォルトではスタイルシートの末尾にクラスを追加する
 */
 @tailwind screens;

@apply

自前のCSS内に既存のユーティリティクラスを展開するには @apply を使用する。

これはHTML内でユーティリティクラスの組み合わせが度々出現し新しいコンポーネントとして抽出したい場合に有用となる。

.btn {
  @apply font-bold py-2 px-4 rounded;
}
.btn-blue {
  @apply bg-blue-500 text-white;
}
.btn-blue:hover {
  @apply bg-blue-700;
}

ルールは一行で綴ることもできるし @apply を複数回呼び出すこともできる:

.btn {
  @apply font-bold;
  @apply py-2;
  @apply px-4;
  @apply rounded;
}

@apply の宣言は通常のCSSの宣言と混ぜることも、もちろん可能である:

.btn:hover {
  @apply bg-blue-700;
  transform: translateY(-1px);
}

@apply でインライン化されたルールは特定の問題を回避するためにデフォルトで !important除去される:

/* ソース */
.foo {
  color: blue !important;
}

.bar {
  @apply foo;
}

/* 生成結果 */
.foo {
  color: blue !important;
}

.bar {
  color: blue;
}

もし既存のクラスを @apply して !important としたい場合は、 @apply の宣言の最後に !important を追加するだけである:

/* ソース */
.btn {
  @apply font-bold py-2 px-4 rounded !important;
}

/* 生成結果 */
.btn {
  font-weight: 700 !important;
  padding-top: .5rem !important;
  padding-bottom: .5rem !important;
  padding-right: 1rem !important;
  padding-left: 1rem !important;
  border-radius: .25rem !important;
}

Sass/SCSS を使用している場合は Sass の補完機能を使用してうまく動くようにする必要がある:

.btn {
  @apply font-bold py-2 px-4 rounded #{!important};
}

@apply は擬似クラスやレスポンシブのバリアントを使ったユーティリティクラスのインライン化には 非対応 なので注意されたい。 適宜擬似クラスやメディアクエリ内にバリアントを使用していないユーティリティクラスを apply してほしい。

/* 動かない: */
.btn {
  @apply block bg-red-500;
  @apply hover:bg-blue-500;
  @apply md:inline-block;
}

/* これならOK: */
.btn {
  @apply block bg-red-500;
}
.btn:hover {
  @apply bg-blue-500;
}
@screen md {
  .btn {
    @apply inline-block;
  }
}

ユーティリティクラスに プレフィクスを設定 していたとしても @apply を使用するときはプリフィクスを省略することが可能である:

/* 両方とも動く */
.btn {
  @apply tw-font-bold tw-py-2 tw-px-4 tw-rounded;
}
.btn {
  @apply font-bold py-2 px-4 rounded;
}

@variants

@variants ディレクティブで定義をラップすることで独自ユーティリティクラスの responsive, hover, focus, active 他の 擬似クラスバリアント を生成可能である。

@variants focus, hover {
  .rotate-0 {
    transform: rotate(0deg);
  }
  .rotate-90 {
    transform: rotate(90deg);
  }
}

このようなCSSが生成される:

.rotate-0 {
  transform: rotate(0deg);
}
.rotate-90 {
  transform: rotate(90deg);
}

.focus\:rotate-0:focus {
  transform: rotate(0deg);
}
.focus\:rotate-90:focus {
  transform: rotate(90deg);
}

.hover\:rotate-0:hover {
  transform: rotate(0deg);
}
.hover\:rotate-90:hover {
  transform: rotate(90deg);
}

バリアントは書いた順番の通りに生成される ということに注意されたい。

例えば hover より focus のユーティリティクラスが優先されるようにしたい場合は hover の あと に focus が来るようにしなければならない:

/* ソース */
@variants hover, focus {
  .banana {
    color: yellow;
  }
}

/* 出力結果 */
.banana {
  color: yellow;
}
.hover\:banana:hover {
  color: yellow;
}
.focus\:banana:focus {
  color: yellow;
}

@規則 である @variants は設定ファイルの variants セクションの値の全てとプラグインによって追加された カスタムバリアント をサポートする。

@responsive

@responsive ディレクティブの中に独自クラスの定義をラップすることでレスポンシブバリアントを生成することが可能である:

@responsive {
  .bg-gradient-brand {
    background-image: linear-gradient(blue, green);
  }
}

デフォルトのブレークポイントではこのように出力される:

.bg-gradient-brand {
  background-image: linear-gradient(blue, green);
}

/* ... */

@media (min-width: 640px) {
  .sm\:bg-gradient-brand {
    background-image: linear-gradient(blue, green);
  }
  /* ... */
}

@media  (min-width: 768px) {
  .md\:bg-gradient-brand {
    background-image: linear-gradient(blue, green);
  }
  /* ... */
}

@media (min-width: 1024px) {
  .lg\:bg-gradient-brand {
    background-image: linear-gradient(blue, green);
  }
  /* ... */
}

@media (min-width: 1280px) {
  .xl\:bg-gradient-brand {
    background-image: linear-gradient(blue, green);
  }
  /* ... */
}

レスポンシブバリアントはスタイルシート末尾の Tailwind の既存のメディアクエリに追加されるため、レスポンシブのプレフィクスが 付与されているクラスは同じCSSプロパティを対象とするレスポンシブではないクラスを常に無効化する。

@screen

@screen ディレクティブを使用すると独自のCSSの値を重複せずブレークポイントを名前で参照するメディアクエリを作成できる。 例えば sm640px のブレークポイントがあったとしてこれを参照するCSSを書く必要がある場合、このような値をコピーしなければいけない通常のメディアクエリ:

@media (min-width: 640px) {
  /* ... */
}

の代わりに @screen ディレクティブを使用してブレークポイントを名前で参照できる:

@screen sm {
  /* ... */
}

theme()

theme() 関数を使えばドット記法を使った Tailwind の設定値を取得することが可能である。

宣言の一部だけをテーマ設定から値を参照する必要がある場合 @apply の代わりに有用である:

.content-area {
  height: calc(100vh - theme('spacing.12'));
}

Tailwind では ネストオブジェクト記法 をデフォルトのカラーパレットの定義に使用しているのでネストされたカラーへアクセスする際ドット記法を使う必要があることに注意されたい。

:x: ハイフンを使用してネストされたカラー値へアクセスしてはいけない

.btn-blue {
  background-color: theme('colors.blue-500');
}

:o: ドット記法を使用してネストされたカラーへアクセスする

.btn-blue {
  background-color: theme('colors.blue.500');
}

他の フロントエンド タグの記事

Cover Image for Promise を可視化する

Promise を可視化する

Promise の生成と実行を記録しPendingのまま残ったPromiseを特定したときのお話

Cover Image for Next.js でブログを作った

Next.js でブログを作った

Next.js のテンプレートを拡張した話