Tailwind CSS v3.1 で追加された機能まとめ

年の瀬が迫り、アンテクアドベントカレンダーもあと少しというところ!
皆様どのようにお過ごしでしょうか?

今回はTailwind CSS v3.1で追加された機能のまとめをご紹介します。
こちらのオフィシャル情報を元にこの記事を書きました。
Tailwind CSS v3.1: You wanna get nuts? Come on, let’s get nuts! – Tailwind CSS
https://tailwindcss.com/blog/tailwindcss-v3-1
What’s new in Tailwind CSS v3.1?
https://www.youtube.com/watch?v=nOQyWbPO2Ds

それでは、ひとつずつ見ていきましょう!

First-party TypeScript types

tailwind.config.jsでカスタマイズする時、何度も公式ドキュメントを見に行っては参照しますよね。
それが今回、先頭に以下の型注釈のコメントを入れるだけで、ヒントが出るようになりました。

/** @type {import('tailwindcss').Config} */

こんな感じでヒントが出ます。これで公式ドキュメントを見にいく回数が減りそうですね。

ちなみに、tailwindcssを最新版にするともうすでに型注釈のコメントが入っています。

Built-in support for CSS imports in the CLI

CLIツールにpostcss-importがビルトインされるようになりました。
コンパイル前のcssは元々このような感じになっています。

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

それを@importを使って書き換えて、さらに以下のように追加ファイルのimportできるようになりました。

@import "tailwindcss/base";
@import "./example-theme.css"; /* 追加ファイル */
@import "tailwindcss/components";
@import "tailwindcss/utilities";

これでメインのcssを汚さずに、きれいに管理できるようになりましたね。

Change color opacity when using the theme function

theme関数を用いた色指定をする場合のアルファチャンネルの設定が、以下のようなスラッシュ構文でできるようになりました。
例えばcssファイルにthemeカラーを参照して色指定する際は以下のような形で指定します。

.example-item {
  background-color: theme(colors.gray.100 / 50%);
}

tailwind.config.jsにてテーマ拡張する際にも同様に使えます。

module.exports = {
  content: [
    // ...
  ],
  theme: {
    extend: {
      colors: ({ theme }) => ({
        primary: theme('colors.red.500'),
        'primary-fade': theme('colors.red.500 / 75%'),
      })
    },
  },
  plugins: [],
}

また、直接タグにも使えます。

<p class="text-[theme(colors.red.500/75%)]">テキスト</p>

まぁ、タグに書くならtheme関数使わずにこれでいい気がします。

<p class="text-red-500/75">テキスト</p>

Easier CSS variable color configuration

CSS変数による色指定にもスラッシュ構文にてアルファチャンネルの設定ができるようになりました。

まずメインのcssに色指定のための変数を書きます。
rgbやhslの値そのもののみを指定します。ここではまだrgb()など付けてはいけません。

:root {
  --color-brand: 255 115 179;
}

そしてtailwind.config.jsにてテーマを拡張します。
はアルファチャンネルの値のプレースホルダーです。ここでrgbなどの指定を含めます。

module.exports = {
  theme: {
    colors: {
      brand: 'rgb(var(--color-brand) / <alpha-value>)',
    }
  }
}

これでタグの方でこんな感じでアルファチャンネルの指定ができるようになりました。

<p class="text-brand/50">テキスト</p>

Border spacing utilities

border-spacing用のユティリティクラスが追加されました。
border-spacingは border-collapse: separate; を設定するときに効きます。
普通のテーブルなら border-collapse: collapse; にすると思うのですが、collapseだとthを position: sticky; で固定した時に、スクロール時にborderが消えてしまうのです。

なので、thを固定したい時は、以下のようにtableタグにborder-separateとborder-spacing-0を一緒に設定する、と覚えておきましょう。

<table class="border-separate border-spacing-0">
  <thead>
    <tr>
      <th class="sticky top-0 z-10 p-4 border-b border-gray-300">項目名</th>
      <th class="sticky top-0 z-10 p-4 border-b border-gray-300">項目名</th>
      <th class="sticky top-0 z-10 p-4 border-b border-gray-300">項目名</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td class="p-4 border-b border-gray-200">コンテンツ</td>
      <td class="p-4 border-b border-gray-200">コンテンツ</td>
      <td class="p-4 border-b border-gray-200">コンテンツ</td>
    </tr>
    ...
  </tbody>
</table>

Enabled and optional variants

enabledとoptionalという擬似クラスのための新しいバリアントが追加になりました。
enabled:は有効な時、つまりdisabledではない時のみに効くようになります。
optional:は文字通り任意の時に効くようになります。必須(required)の時は効きません。

enabled:の使いどころとしては、ボタンがenabledな時のみにhoverのスタイル指定ができるというところです。
これまではhoverのスタイルを指定するとdisabledの時にhoverしてもそれが効いてしまうため、hover:disabled:でそのスタイルを打ち消す必要がありました。これからはdisabledする可能性のあるボタンのhoverスタイルは、以下のような形でhover:enabled:で設定すると後で打ち消すスタイルを書く必要がなくなります。

<button type="button" class="bg-indigo-500 hover:enabled:bg-indigo-400 disabled:opacity-75  ..." disabled>
  ボタン
</button>

次に、optional:のほうに移ります。optional:はpeerクラスと一緒に使います。groupとgroup-hover:を使ったことある方でしたら、使い方が似ているのであんな感じかと思っていただいたら分かりやすいかと思います。一つ違うのはgroup-*は子要素に効くのに対して、peer-*は兄弟要素間で効くというところです。peerは同僚とか同級生とか仲間とか、そんな意味の単語です。例えば peer pressure(同調圧力という意味)という表現をよく見かけますね。英語が苦手な方はpeerはsiblingと覚えるといいと思います。

本題に戻すと、例えばフォームで必須の時だけ表示させたいメッセージがあるとします。
まず必須かどうか判断するべきinput要素にpeerクラスを付けます。そのすぐ下にメッセージ用のタグを追加し、peer-optional:に続けてhiddenを指定します。
そうすると、peerクラスの要素がデフォルトの任意の状態、つまりoptionalの状態だと、兄弟要素であるメッセージはhiddenになり表示されず、逆にpeerクラスの要素がrequired(必須)の時、つまりoptionalでない状態の時、兄弟要素であるメッセージが表示されます。

<form>
  <div>
    <label for="email" ...>Eメール</label>
    <div>
      <input required class="peer ..." id="email" />
      <div class="peer-optional:hidden ...">
        必須です
      </div>
    </div>
  </div>
  ...

条件によってcssで表示を切り替えられるのは便利ですね。プログラムを組み込むエンジニアさん自身でtailwindのクラスを入れる場合は使えそうですね。

Prefers-contrast variants

メディアクエリでprefers-contrastというものがあるのをご存知ですか?私は全く知らなかったです…。
ユーザーがOSで設定するものとのことです。特にいじらなかったら指定なしの扱いになるとのことです。
参考)prefers-contrast – CSS: カスケーディングスタイルシート | MDN

素のcssで例えばprefers-contrast: moreのスタイルを指定する時はこんな感じのメディアクエリを書きます。

@media (prefers-contrast: more) {
  ...
}

今回Tailwindでは、以下のような形でcontrast-moreとcontrast-lessというバリアントでスタイル指定ができるようになりました。

<p class="opacity-75 contrast-less:opacity-50 contrast-more:opacity-100">
  テキスト
</p>

まだまだ知らないことがありますね。もし使う機会があれば使ってみてください。

Style native dialog backdrops

htmlのdialog要素のブラウザサポートが進み、もう実案件で使用しても良さそうなところまで来ています。

今回TailwindcssではJavascriptのshowModal()でdialogを開いた時に追加される背景用の::backdrop擬似要素に対してスタイリングできるbackdropモディファイアが追加されました。
::backdrop擬似要素にはネイティブのスタイルが当たっていて、薄いグレーで表示されます。
それを以下のように色やblurなど自由にスタイリングできます。

<dialog class="backdrop:bg-slate-900/10 backdrop:backdrop-blur-sm">
  <form method="dialog">
    モーダルコンテンツ
  </form>
</dialog>

dialog要素とTailwindの組み合わせ、いいですね!どうしても手作りモーダルは見た目の再現のためにdivだらけになって嫌だったのですが、これだとシンプルに書けそうですね。

Arbitrary values but for variants

クラス指定に任意値が入れられるようになったタイミングで、Tailwindがグッと実用的になったように感じた方も多いはず。今度は、なんとバリアントの方も任意値が使えるようになったのです!
&(アンパサンド)を利用して、直下なら「>」、スペースは「_」を利用、あとは「:first-child」や「:nth-child()」など組み合わせてかなり柔軟に指定できます。

<ul role="list" class="hover:[&>li:nth-child(2)>div>p:first-child]:text-indigo-500 [&>*]:p-4 [&>*]:bg-white [&>*]:rounded-lg [&>*]:shadow space-y-4">
  ...
</ul>

バリアントの方に任意値が使えるメリットとしては、プログラムの都合で子要素にクラスを書けない、もしくは書きたくない時に親要素の方で子のスタイル指定ができるというところです。:nth-child()などを使えばレイアウトの都合で発生する例外的なスタイルも親要素に書けますね。

さて、Tailwindcss v3.1の追加機能は以上になります。どんどん使いやすくなりますね。
次回はv3.2の追加機能についてまとめようと思います。ではでは!

TAGS使用タグ一覧