Tailwind CSS V4を使ってたが、カスタムプラグインの入れ方がわからなくて一回V3に戻そうとしたら、今度はV3特有の問題にぶち当たって、結局V4でプラグインのインポート方法を見つけて解決した話。
迷走したおかげで両バージョンの違いも理解できたし、未来の自分(と同じ問題で悩む人)のためにメモしておく。
なぜV4からV3に戻そうとしたのか
CSSだけでスタイリングしたかった
そもそもの発端は、remを使いたいのにいい感じに書けないことでした。
const className = 'text-sm' // どれくらいのサイズかわからん const className = 'text-[10px]' // これは嫌だ const className = 'text-[0.625rem]' // こうしたいけど見づらい const className = 'text-10px' // こう書いたら font-size: 0.625rem が指定されてほしい
V3だと簡単にできそうやった
V3の場合、tailwind.config.jsで簡単に設定できる。
// tailwind.config.js
theme: {
fontSize: {
'10px': '0.625rem'
}
}
V4だとFunctional utilitiesを使う必要がある
V4の場合はFunctional utilitiesを使う必要があるらしい?
// 動かないよ @utility text-*px { font-size: calc(var(--value, integer) / 16)rem; }
でも、*には特定のものしか受け付けなさそうで、思ったようにいかない。
カスタムプラグインを作る必要があった
結局カスタムプラグインを作る必要があることがわかったが、V4でのプラグインの入れ方がわからなかった。
結果「もうV3に戻すしかないか!」となった。
V3に戻そうとして新たな問題に直面
shadcn/uiのカラーが適切に動かない
V4ではprimary/50とかでテーマカラーのopacity指定がデフォルトで可能なので、shadcn/uiのコンポーネントのカラーが適切に設定されていた。
でもV3では同じ記法が使えないらしい...
Claude Codeにすべてを任せた弊害が出た...
primaryの設定自体はうまく行ってるはず。shadcnのテーマを継承している。
theme: {
extend: {
colors: {
primary: {
DEFAULT: 'var(--primary)',
foreground: 'var(--primary-foreground)',
},
}
}
}
V3で同様記法を使うためのコツ
調べてみると、V3で同様の記法を使うにはちょっとコツが要るらしい。
新たな学びを得た。
theme: {
extend: {
colors: {
primary: {
DEFAULT: 'rgb(from var(--primary) r g b / <alpha-value>)',
foreground: 'rgb(from var(--primary-foreground) r g b / <alpha-value>)',
},
}
}
}
V4でも@pluginでプラグイン入れられるじゃないか!
迷走してる途中で、V4でも@pluginディレクティブでプラグインが入れられることを発見。
カスタムのやつもJSファイルを別で作って入れられるらしい。
なぜかはまったインポート問題
import plugin from 'tailwindcss/plugin';
// default exportされてるのか...node_modulesまで型定義見に行かないと参照できなかった...
const customPlugin = plugin(({ addUtilities }) => {
addUtilities({
'.test-1px': {
'margin-top': 'calc(1px)',
},
});
});
export default customPlugin; // ここもdefault exportしないといけないみたい
型定義を見るまでdefault exportやって気づかんかった。
最終的な解決方法
結局、V4で以下のような感じでカスタムプラグインを作成して解決。
import plugin from 'tailwindcss/plugin';
const customPlugin = plugin(({ matchUtilities }) => {
const allowedFontSizes = [10, 11, 12, 13, 14, 15, 16, 18, 20, 24, 28, 32, 40, 48, 56, 64, 128];
const fontSizeValues = allowedFontSizes.reduce((acc, size) => {
acc[`${size}px`] = `calc(var(--spacing) / 4 * ${size})`;
return acc;
}, {});
matchUtilities(
{
text: value => ({
fontSize: value,
}),
},
{
values: fontSizeValues,
}
);
});
// biome-ignore lint/style/noDefaultExport: Allow default export for plugin
export default customPlugin;
/* app.css */ @import 'tailwindcss'; @plugin "./fontSizePxToRem.js";
これでtext-10px、text-24pxみたいに書けるようになった!
学んだこと
V3とV4の違い
迷走したからこそ得られた知見
- V3のopacity対応方法
- V4のプラグインインポート方法
- default exportの重要性
最初からV4のドキュメントをちゃんと読んでればよかったんやけど、迷走したおかげで両方のバージョンの差異を理解できたのは良かったかもしれない。