Tailwind CSS v4 の新しい機能いろいろ
現在 Tailwind CSS v4 のベータ版がリリースされています。
v4 ではネイティブ CSS の機能から逸脱しない CSS First なアプローチが多く採用されています。本記事では Tailwind CSS v4 の新機能と実際に触ってみた所感を書き連ねます。
インストール
インストールは以下の方法が用意されています。
新規でインストールする場合、Vite プラグインもしくは、PostCSS プラグインとしてインストールするのが基本的な方法になりそうです。
私は v3 からのアップグレードをしましたが、アップグレードコマンドで軽微なスタイル崩れが発生しました。そのため、アップグレードする場合ビジュアルリグレッションテストでデグレがないことをテストしてもいいかもしれません。
テーマの設定
早速 Tailwind CSS v4 の肝となる CSS ファイルでのテーマ設定についてです。
v3 までではtailwind.config.jsにテーマの設定を記載していましたが v4 からはtailwind.config.jsを使わず、CSS ファイルに設定を記述していくことになります。
テーマの設定はネイティブ CSS のカスケードレイヤーの機能を活用して CSS ファイルを修正していくことになります。
CSS ファイルの冒頭で@import "tailwindcss"することでtheme→base→components→utilities(優先度 低 → 高)という 4 つのレイヤーが用意されます。
color,font,text などのテーマはthemeのレイヤーで更新することになります。
テーマの追加・更新
CSS ファイルに@import "tailwindcss"をすることで、Tailwind CSS デフォルトのユーティリティクラスの CSS が生成されます。

では、テーマを上書きしてみます。
@themeディレクティブで変更したいクラスと値を書き込んでいきます。
デフォルトで用意されているcolor-red-50とcolor-red-100に対して値を設定すると、上書きされた値が生成されることが分かります。

また、存在しなかったテーマを追加することで、新規でテーマを生成することもできます。

名前空間ごとの一括更新
color-〇〇だけ更新、text-〇〇だけ更新といったような特定のクラスを更新というケースだけではなく、color全部、text全部を一括で指定することもできます。color,text,fontなどひっくるめて全部を一括指定することもできます。
color,text,fontなどのテーマの種類は Namespace reference からご確認ください。
@theme {
/* カラーとフォントの設定を無効化 */
--color-*: initial;
--font-*: initial;
}
@theme {
/* すべてのテーマの設定を無効化 */
--*: initial;
}
*でテーマの設定を無効化することで、Tailwind CSS のリセット CSS を効かせつつ、テーマを無効化することができます。
ただ私としては、デザインシステムの逸脱を防ぐことが Tailwind CSS の考え方でもあるので、あまり常用するものでもないのかなという所感です。
対象ファイルの自動検出
Tailwind CSS v3 では、以下のようにtailwind.config.jsのcontentに対象ファイルを指定しておかなければなりませんでした。
// v3の設定
module.exports = {
content: [
"./src/pages/**/*.{js,ts,jsx,tsx}",
"./src/components/**/*.{js,ts,jsx,tsx}",
"./src/app/**/*.{js,ts,jsx,tsx}",
],
// 略
};
v4 では、.gitignoreで指定されているファイルを無視して、それ以外のファイルで自動検出できるようになります。
また、.gitignoreで指定しているけど Tailwind CSS の検出対象にしたいファイルは@sourceディレクティブで明示的に指定することができます。@import "tailwindcss" source(none)で自動検出を無効にすることもできます。
任意値設定([])の簡素化
[]が一部いらなくなる
v3 でopacity-[1],z-[9999]のように任意値を適用するときに使っていた[] (arbitrary values) ですが、v4 ではデザイントークンではないものに関して、[]をつけずにopacity-1,z-9999のように指定できるようになりました。
Spacing の動的生成
Spacing のスタイルはすべて spacing の 1 を基準に計算されて、生成されるようになりました。
例えば
-
p-2はpadding: calc(var(--spacing) * 2) -
mt-4はmargin-top: calc(var(--spacing) * 4)
のようなイメージです。
例えば、従来 60px(15rem) がほしいときに Tailwind CSS デフォルトの Spacing に15は用意されていなかったので、h-15のように指定できなかったのですが、v4 ではh-15が1rem * 15と動的に計算してくれるので、[]を使わなくても良くなりました。
7px をh-7pxやh-7のように指定することはできず、h-[7px]と指定しなければいけないのは変わらないので、デザインシステムが崩れることもないです。
補足として spacing の 1 をデフォルトの 0.25rem から上書きすることもできます。
@theme {
--spacing: 0.5rem;
}
data 属性
data 属性でも従来[]をくくっていましたが、不要になります。簡潔。
- <div class="opacity-50 data-[selected]:opacity-100" data-selected>
+ <div class="opacity-50 data-selected:opacity-100" data-selected>
ネイティブ CSS のモダン機能のサポート
コンテナクエリ
親要素のサイズに応じて子要素のスタイルを適用するコンテナクエリが追加プラグインなしで標準サポートされました。
コンテナクエリあまり使ったことがないのでもっと使っていきたい...。
<div class="@container">
<div class="grid grid-cols-1 @sm:grid-cols-3 @lg:grid-cols-4">
<!-- ... -->
</div>
</div>
textarea要素の高さを自動調整するfield-sizing:content
textareaの高さを文字量にあわせて、自動調整するfield-sizing:contentが v4 から利用可能になりました。
<textarea class="field-sizing-content ..."></textarea>

field-sizing-contentが適用されたtextarea要素
子孫要素全てにスタイルを適用する**バリアント
これまでクラスに頭に*:をつけることで親要素から 1 つ下の子要素すべてに同じスタイルを適用することができました。
v4 では**:をつけることで、子要素だけではなくすべての子孫要素に同じスタイルを適用することができます。
<div class="**:p-4"></div>

**で親要素から孫要素にp-4とborderを適用
v4 でもtailwind.config.jsを使う
@configディレクティブを使うことで、従来のtailwind.config.jsで設定を適用することができます。
[]が不要になったところでも引き続き[]を使うことができたり、oklch での色指定に変更されても引き続き rgb や 16 進数カラーコードが使用できたりと、破壊的な変更を少なくする意図が垣間見れます。
v3 から v4 で変更内容は多いので、段階的に移行する手段があることは良いことだと思います。
@config "../../tailwind.config.js";
番外編
form 要素にデフォルトのスタイルが適用されるかもしれない
Tailwind CSS 作者の Adam Wathan さんが、「フォーム要素が初期状態でスタイルが適用されておらず見た目で識別しづらいことについて、デフォルトスタイルがほしいかどうかの意見を求む」というポストをされています。
個人的にはデフォルトスタイルを外し忘れたときが怖いので、オプションで有効にできるぐらいが嬉しいかなと思いました。
プリミティブトークンで設定して、セマンティックトークンで使える
blue-50,blue-100,gray-50,,のようなプリミティブトークン(グローバルトークン)で設定し、その中でprimary,secondary,accentのような特定の意図をもたせたセマンティックトークン(エイリアストークン)を HTML 上で使いたいケースが私はよくあります。
従来でも実現することはできましたが、CSS ファーストな設定になり CSS 変数を使えるようになったことで、より直感的に扱うことができると感じています。
CSS ファイルにvar(プリミティブトークンのCSS変数)の形でセマンティックトークンを定義してあげることで、プリミティブトークンとセマンティックトークンの 2 つの階層を扱うことができます。
@theme {
--color-primary: var(--color-blue-600);
--color-error: var(--color-red-600);
}

最後に
最後まで読んでくださってありがとうございます。
今回 Tailwind CSS v4 を触ることでネイティブ CSS の凄まじい進化に追従できてないことを痛感しました。v4 の正式リリースを待ちつつも、ネイティブ CSS のキャッチアップもしていきたいです。
Discussion