この記事の概要
2025年1月22日にTailwind CSSのv4が正式にリリースされました。
この記事を執筆している2025年2月16日現在、私は合計4つのサイトでv3からv4へアップグレードを実施しています。
公式から提供されているアップグレードツールで事足りる部分も多いですが、一部は手動で変更しないといけませんでした。
私が遭遇した問題と、その対処法について記事にします。
対応したサイトがReact, Svelte, Astroと色々なパターンがあったため、特定のフレームワークや条件でだけ起きる問題というのもあると思います。
調べて分かっている分は記載しますが、漏れがあったらすみません。
遭遇した事象
@referenceは自動で挿入されない
VueやSvelte、Astroを使用している場合、ファイルの中に<style>を定義してスタイルを当てていることがあると思います。
<style>内で@applyを使用している場合、v4では@referenceを使用し、エントリーポイントのCSSを指定する必要があります。
自動アップグレードではこちらに対応してくれないため、手動で挿入する必要がありました。
余談ですが、先ほどのリンクにあるように@applyを使用せずにCSSカスタムプロパティを使う書き方もあるものの、その方が時間はかかりそうな印象です。
theme関数の挙動が変わり、自動で変更されない
もともと、このようなクラスを書いていました。
<div class="grid-cols-[minmax(0,theme('width.60'))_1fr]">
この書き方だとまったくスタイルがあたらず、以下のリンクの内容を参考にしつつ書き換えました。
<div class="grid-cols-[minmax(0,theme(spacing.60))_1fr]">
この書き方だと、スタイルは当たるのですが自分で定義し直したspacingの値ではなく、デフォルトのspacingの値をもとにスタイルが生成されていました。
意図した挙動なのかそうでないのかは分かりませんが、自分で定義したspacingの値を使うにはこのように書けば大丈夫でした。
<div class="grid-cols-[minmax(0,calc(var(--spacing)*60))_1fr]">
若干冗長になった感じと「そもそもtheme関数を使わなくなっちゃってるじゃん」という感じはしますが、やりたいことはこれで実現できています。
エントリーポイントのhtmlが自動クラス名抽出の対象にならない
今のところ、この挙動はSvelteKitでのみ起こっています。
v3まではtailwind.config.jsにcontent: ["./src/**/*.{html,js}"]のような指定をする必要がありましたが、v4からは指定せずとも自動でクラス名を抽出してくれるようになりました。
なりましたが、SvelteKitのsrc/app.htmlに書いたクラスは抽出の対象になりませんでした。
そのためsrc/app.cssに以下の指定を追加する必要があります。
@import "tailwindcss";
+ @source "./app.html";
ちなみに以下のドキュメントにあるように、node_modulesなど.gitignoreで除外されているものを対象に取りたいとき使うのがメインの使い方なようです。
leading-tightなどがドキュメントから消えているがこれまで通り使用できる
私のドキュメントの見方がおかしいのかもしれませんが……。
以下はv4のドキュメントで、
以下はv3のドキュメントです。
予約語(?)っぽいleading-クラスはleading-none以外記載がなくなっているように見えるのですが、以下のデフォルトテーマ変数を見るとちゃんと登録されています。
クラス名としてはleading-tightでもtext-lg/looseのような記法でも、問題なく使えました。
独自のshadowやroundedを定義しているとアップグレードツールの挙動で齟齬が起きる
v4では一部のユーティリティがリネームされました。
アップグレードツールを使うと、これに沿ってクラス名のshadowをshadow-smへ、shadow-smをshadow-xsのように変換してくれます。
ただ、アップグレードツールは同時にtailwind.config.jsに記載されていたtheme変数をglobal.cssのようなファイルに転記してくれるのですが、このときに齟齬が起きます。
自前でshadowを定義していた場合、以下のようになります。
--shadow: 独自の値;
つまり、クラス名はshadow-smに変わっているのに変数定義がshadowになってしまい、サイト中の影が消えます。
対策としてはglobal.cssの命名を--shadow-smに変えるだけですが、微妙に原因の分かりづらい挙動だと思いました。
theme変数にキャメルケースを使っていると、CSSカスタムプロパティはリネームされるのにクラス名にはリネームされない
tailwind.config.jsにて、このような設定をしていました。
module.exports = {
theme: {
colors: {
surface: "#fff",
surfaceVariant: "#edeeee",
...
}
}
}
この場合、bg-surfaceVariantなどのクラス名でカスタムした値を利用できます。
アップグレードツールを使うと、このように変換されました。
@theme {
--color-surface: #fff;
--color-surface-variant: #edeeee;
...
}
この場合、クラス名をbg-surfaceVariantからbg-surface-variantに変更しないといけないのですが、アップグレードツールはそうしてくれませんでした。
両方変換するか、両方触らずにいてくれたら楽なのですが……。
もしかしたらtailwind.config.jsの時点でsurfaceVariantを""で括っていたら変換されずに済んだのかもしれませんが、検証できていません。