💨

Tailwind CSS v3.2で追加された主な機能

2022/10/21に公開約10,000字

はじめに

京都のスタートアップでエンジニアをしている、KIOといいます。

昨日(10月20日)、Tailwind CSSのv3.2が正式にリリースされました。
この記事では新たに追加された主な機能についてざっくりとまとめます。

初めての技術記事投稿なので、読みづらい箇所が多々存在するかと思いますがご了承ください🙇‍♂️
いいね・コメント・指摘は大歓迎です!よろしくお願いします!

v3.2の記事を読んでいて、ヘッダーの右側にShowcaseの項目が増えているのを発見しました👀
誰もが知るサービスや、個性的なデザインのウェブサイトなど、Tailwind CSSで構築された色々なウェブサイトがまとめられていたので気になる方は是非ご覧ください!

この記事について

この記事は👇の簡単なまとめ記事です。
より厳密な情報・詳細については以下サイトをご確認ください。

v3.2で追加された機能

追加された主な機能は以下になります。

  • @config
  • @supports
  • aria-*
  • data-*
  • max-*、動的なブレークポイントの生成
  • group-[...] peer-[...]による動的なバリアントの生成
  • ネストされたgroup-*や複数のpeer-*に対して、バリアント修飾子を設定できるように
    @containerにも...)
  • matchVariantを使用した動的バリアントの生成
  • @container(コンテナークエリ)

@config

@configは1つのプロジェクト内で複数の設定ファイルを使用できるようにするディレクティブです。

👇 公式サイトの例

@config "./tailwind.config.js"
@tailwind base;
@tailwind components;
@tailwind utilities;

Tailwind CSS公式の例としては、「顧客向けと管理者で設定ファイルを使い分けたいとき」が例として挙げられていました。

postcss-import をプロジェクトで使用している場合は注意が必要です。
cssファイル内で @importを使用している場合、@configを先頭に置くことはできず全ての@importの後に@configを記述する必要があります。
これは「全ての@importを先頭に置かなければならない」というCSSの仕様に、postcss-importが従っているためです。

業務では、複数リポジトリで共通利用しているリポジトリ(コンポーネント)のTailwind.configをnpmパッケージとして管理しpresetsに設定していました。
@config によってこの点が解消できそうです。

@supports

supports-[...]内部で生成されるバリアントを使用して、ユーザの使用ブラウザのサポート状況に基づいたスタイルを設定できるようになりました。

👇 公式サイトの例

<div class="supports-[display:grid]:grid">
  <!-- ... -->
</div>
<div class="supports-[grid]:grid">
  <!-- ... -->
</div>

この例の場合、ユーザの使用ブラウザがdisplay:gridに対応している場合gridが適用されます。
また、supports-[...]にはTailwind CSSで定義されているユーティリティクラスや、and(結合条件)・or(非結合条件)・not(否定)が使用可能です。

Tailwindの初期設定時に autoprefixer をプラグインとして設定しているとベンダープレフィックスが自動で付いていましたが@supportsによってより明示的なスタイリングが可能になりそうですね。

この@から始まるCSSの書式はアットルールと呼ばれるもので、
CSSのルールについて規定できるものです。有名なものだと@mediaがありますね!

@media screen and (min-width:680px) { 
p {
   font-size: 16px;
  }
}

aria-*

aria-[...]で生成されるバリアントを使用してARIA属性に基づいたスタイルを設定できるようになりました。

<div aria-checked="true" class="bg-gray-600 aria-checked:bg-blue-600">
    <p class="text-white">aria-checked="true"</p>
</div>
<div aria-checked="false" class="bg-pink-600 aria-checked:bg-blue-600">
    <p class="text-white">aria-checked="false"</p>
</div>

この場合👇の写真のようになります

aria-checkedの値がクリックイベントなどによって動的に変更する場合、aria-checkedの値によって設定されるスタイルを動的に変化させることができます。

Tailwind CSSにデフォルトで設定されている値
Modifier CSS
aria-checked &[aria-checked=“true”]
aria-disabled &[aria-disabled=“true”]
aria-expanded &[aria-expanded=“true”]
aria-hidden &[aria-hidden=“true”]
aria-pressed &[aria-pressed=“true”]
aria-readonly &[aria-readonly=“true”]
aria-required &[aria-required=“true”]
aria-selected &[aria-selected=“true”]

👇 公式サイトの例

<table>
  <thead>
    <tr>
      <th
        aria-sort="ascending"
        class="aria-[sort=ascending]:bg-[url('/img/down-arrow.svg')] aria-[sort=descending]:bg-[url('/img/up-arrow.svg')]"
      >
        Invoice #
      </th>
      <!-- ... -->
    </tr>
  </thead>
  <!-- ... -->
</table>

テーマとして独自に定義する必要がない(1度しか使わない)場合は、aria-[...]を使用して、任意の値を設定することもできます。

👇 公式サイトの例

<table>
  <thead>
    <tr>
    <th aria-sort="ascending" class="group">
      Invoice #
      <svg class="group-aria-[sort=ascending]:rotate-0 group-aria-[sort=descending]:rotate-180"><!-- ... --></svg>
    </th>
    <!-- ... -->
    </tr>
  </thead>
  <!-- ... -->
</table>

group-aria-*peer-aria-*を使用して、親要素・兄弟要素を対象にすることもできます。

data-*

タグに指定したデータ属性に対して、data-[...]で生成されるバリアントを使用してスタイルを設定できるようになりました。

<p data-country="italy" class="data-[country=italy]:text-green-600">
  イタリア
</p>
<p data-country="japan" class="text-red-600 data-[country=italy]:text-green-600">
  日本
</p>

この場合👇の写真のようになります

この例ではデータ属性として、国名を設定しています。
そのためclassで指定した条件の場合のみスタイルが適用されます。
data-country="japan"の場合、data-[country=italy]という条件に該当しないのでtext-red-600が設定されます。

max-*、動的なブレークポイントの生成に対応

max-widthをブレークポイントとしたレスポンシブバリアントが追加されました。
(設定されているのは@media not all and (min-width: ...px) { ... })

👇 公式サイトの例

<div class="max-lg:p-8">
  <!-- ... -->
</div>

この例の場合、ユーザの使用デバイスが1024px以下まで p-8が適用されます。

これまでmax-*は、widthheightを指定する場合のみ使用されていましたが、v3.2からはメディアクエリにも使用されるようになります。

Tailwind CSSにデフォルトで設定されている値
Modifier Media query
max-sm @media not all and (min-width: 640px) { ... }
max-md @media not all and (min-width: 768px) { ... }
max-lg @media not all and (min-width: 1024px) { ... }
max-xl @media not all and (min-width: 1280px) { ... }
max-2xl @media not all and (min-width: 1536px) { ... }

👇 公式サイトの例

<div class="md:max-lg:flex">
  <!-- ... -->
</div>

続けて書くことで範囲を指定することも可能です。

これまでTawildin CSSは、min-widthをブレークポイントとしたバリアント(smmdなど)を用意していました。
これは、Tailwind CSSがモバイルファーストのCSSフレームワークであるためで、Tailwind CSSの生みの親であるAdam Watson氏はsmmdを使用することを薦めています。

加えて、min-[...] max-[...]を使用することで任意の値を設定できるようになりました。
👇 公式サイトの例

<div class="min-[320px]:text-center max-[600px]:bg-sky-300">
  <!-- ... -->
</div>

この例の場合

  • 320pxを超えるとtext-centerが適用
  • 600pxまではbg-sky-300が適用

このようになります。

group-[...] peer-[...]による動的なバリアントの生成

カスタムのgroup-[...] peer-[...]バリアントを作成できるようになりました。

👇 公式サイトの例

<div class="group is-published">
  <div class="hidden group-[.is-published]:block">
    Published
  </div>
</div>

この例の場合、group-[.is-published]が指定されているdiv要素はblockが適用されPublishedが表示されます。

👇 公式サイトの例

<div>
  <input type="text" class="peer" />
  <div class="hidden peer-[:nth-of-type(3)_&]:block">
    <!-- ... -->
  </div>
</div>

&を使用することで指定したセレクタが適用された要素の、最終セレクタに目印をつけておくことができます。

Adam氏は「この機能は生涯で3回程度しか使用しないでしょう。」 とおっしゃっていたので、記憶の片隅に留めておくくらいでいいでしょう。

ネストされたgroup-*や複数のpeer-*に対して、バリアント修飾子を設定できるように

これまでのTailwind CSSではgroupがネストしている場合、それぞれを区別することができせんでした。
これに対して、バリアント修飾子が追加されました。
これは後述する@containerバリアントに対しても使用できます。

背景色に対して不透明度を設定する時に用いていたもの同様、 /を用います。

<button class="bg-sky-500/75 ..."></button>

👇 公式サイトの例

<div class="group/sidebar bg-pink-300">
  <p>sidebar</p>
  <div class="group/navitem bg-green-300">
    <p>navitem</p>
    <p class="bg-purple-300 group-hover/sidebar:text-white group-hover/navitem:text-green-300">
      hoge
    </a>
  </div>
</div>

この例の場合、
sidebar がhoverされている時
hogeのテキストカラーはtext-whiteが適用される

navitem がhoverされている時
hogeのテキストカラーはtext-green-300が適用される
hogehover時もnavitemの子要素のため同様)

matchVariantを使用した動的バリアントの生成

matchVariantという新しいプラグインAPIによって、動的バリアントを生成することが可能になりました。

今回のアップデート内容である

  • max-[...]
  • min-[...]
  • group-[...]
  • peer-[...]
  • aria-[...]
  • data-[...]
  • group-{何らかのmodifier}-[...]
  • peer-{何らかのmodifier}-[...]

にはこのmatchVariant使用されています

Tailwind CSSの`supports`の例
supportsVariants: ({ matchVariant, theme }) => {
    matchVariant(
      'supports',
      (value = '') => {
        let check = normalize(value)
        let isRaw = /^\w*\s*\(/.test(check)

        // Chrome has a bug where `(condtion1)or(condition2)` is not valid
        // But `(condition1) or (condition2)` is supported.
        check = isRaw ? check.replace(/\b(and|or|not)\b/g, ' $1 ') : check

        if (isRaw) {
          return `@supports ${check}`
        }

        if (!check.includes(':')) {
          check = `${check}: var(--tw)`
        }

        if (!(check.startsWith('(') && check.endsWith(')'))) {
          check = `(${check})`
        }

        return `@supports ${check}`
      },
      { values: theme('supports') ?? {} }
    )
  },

[]に指定したCSSプロパティが、matchVariantでよしなに成形されています。

<div class="supports-[display:grid]:grid">
    <!-- ... -->
</div>

👆は結果として、このように出力されます。

.supports-\[display\:grid\]\:grid {
    display: grid;
}

また、CSS が生成される順序に意味がある場合sort()matchVariantを使用することができます。

@container(コンテナークエリ)

@containerコンテナークエリを使用可能にするプラグインが公式から発表されました。

公式

👇 の方がstar数が多く最初間違えました、、(執筆当時)

@を使用することで、その他のメディアクエリと区別しています。

👇 公式サイトの例

<div class="@container">
  <div class="@lg:underline">
      <!-- ... -->
  </div>
</div>
生成されるCSS
.\@container {
    container-type: inline-size;
    
    @container (min-width: 32rem)
	.\@lg\:underline {
	    -webkit-text-decoration-line: underline;
	    text-decoration-line: underline;
	}
}
Tailwind CSSにデフォルトで設定されている値
Name CSS
@xs @container (min-width: 20rem)
@sm @container (min-width: 24rem)
@md @container (min-width: 28rem)
@lg @container (min-width: 32rem)
@xl @container (min-width: 36rem)
@2xl @container (min-width: 42rem)
@3xl @container (min-width: 48rem)
@4xl @container (min-width: 56rem)
@5xl @container (min-width: 64rem)
@6xl @container (min-width: 72rem)
@7xl @container (min-width: 80rem)

@[...]によって任意の値を適用させることも可能です。
👇 公式サイトの例

<div class="@container">
  <div class="block @[618px]:flex">
    <!-- ... -->
  </div>
</div>

また、group-*peer-*と同様に /を使用することで、名前付きのコンテナーを生成できます。

<div class="@container/main">
  <!-- ... -->
  <div>
    <div class="block @lg/main:flex">
      <!-- ... -->
    </div>
  </div>
</div>

まとめ

新規で追加された機能については tailwindPLAY👇 で試せます!
https://play.tailwindcss.com/

Tailwind CSSのv3.2で新規追加された主な機能についてざっくりとまとめました。

今回記事を書いていてTailwind CSSは、もうほとんど成熟していて、あとはCSSの最新の動向に対応する形でのアップデートが主になるのかな。なんて思ったりしました。

最後まで読んでくださり、ありがとうございました!
記事について疑問やご指摘があれば是非、コメントなどからお願いいたします。

Discussion

ログインするとコメントできます