Tailwind CSS v4でサイトを新規に建てたら、設定ファイルを一度も書かなかった
ポートフォリオサイトをAstro 5 + Tailwind CSS v4で新規構築した。tailwind.config.jsなしで完成したCSS-first設定の実際と、dark:バリアントのデフォルト挙動で実際にハマった話を書く。
自分の営業用ポートフォリオサイトをAstro 5 + Tailwind CSS v4で新規に作った。作り終わってpackage.jsonを見返して気づいたのだが、tailwind.config.jsを一度も書いていない。v3を触ったことがある人なら「Tailwindのプロジェクト設定といえばまずconfig」という感覚があると思うが、v4ではそれが本当に要らなくなっていた。
この記事は網羅的な新機能リストではなくて、実際にv4でサイトを1つ建てて「何が楽だったか」「どこで戸惑ったか」の記録だ。移行ではなく新規構築の話なので、v3からの大規模移行の苦労話は書けない。その代わり、v4を素の状態から使ったときの実感を正直に書く。
インストールがパッケージ2つで終わる
Astroプロジェクトの場合、入れるのはtailwindcssと@tailwindcss/viteの2つだけ。実際のうちのpackage.jsonのdependenciesはこうなっている。
"dependencies": {
"@astrojs/sitemap": "^3.7.0",
"@tailwindcss/vite": "^4.1.18",
"astro": "^5.17.1",
"tailwindcss": "^4.1.18"
}
v3時代のAstroでは@astrojs/tailwindという公式インテグレーションを挟むのが定番だったが、v4はViteプラグインとして直接刺さる。astro.config.mjsはこれで全部だ。
import { defineConfig } from 'astro/config';
import tailwindcss from '@tailwindcss/vite';
import sitemap from '@astrojs/sitemap';
export default defineConfig({
site: 'https://example.com',
vite: {
plugins: [tailwindcss()]
},
integrations: [sitemap()]
});
postcss.config.jsも無い。tailwind.config.jsも無い。設定と呼べるものはCSSファイルの中にしか存在しない。セットアップで詰まる要素がほぼ消えたので、Astro + Tailwindでブログを立ち上げる手順のような作業は体感でかなり短くなった。
テーマ定義は@themeでCSSに直接書く
v4の柱がこれ。カラーパレットやフォントの定義を、JSオブジェクトではなくCSSの@themeディレクティブに書く。うちのサイトのCSSエントリファイル(global.css)の冒頭はこうなっている。
@import "tailwindcss";
@theme {
/* ダークネイビー + シアン パレット */
--color-primary-400: #38BDF8;
--color-primary-500: #0EA5E9;
--color-primary-600: #0284C7;
--color-accent-400: #FBBF24;
--color-accent-500: #F59E0B;
--font-sans: 'Inter', 'Noto Sans JP', system-ui, -apple-system, sans-serif;
--font-display: 'Poppins', 'Noto Sans JP', system-ui, -apple-system, sans-serif;
}
--color-primary-500と書けばbg-primary-500やtext-primary-500がそのまま使えるようになる。命名規則(--color-*が色、--font-*がフォントファミリー)を覚えるだけで、v3のtheme.extendでやっていたことは全部書ける。
使ってみて地味に効いたのは、@themeの値がそのままCSSカスタムプロパティとして出力されることだ。Tailwindのユーティリティに乗らない自作CSSからも、同じ値をvar()で参照できる。うちのサイトではナビリンクのアンダーラインアニメーションを素のCSSで書いているが、色はテーマから引いている。
.nav-link-underline::after {
content: '';
position: absolute;
bottom: -2px;
left: 0;
width: 0;
height: 2px;
background: var(--color-primary-600);
transition: width 0.3s ease;
}
v3でこれをやろうとするとtheme()関数を使うか、色をハードコードして二重管理するかだった。「ユーティリティで書ける部分」と「素のCSSで書きたいアニメーション」が同じ変数を見てくれるので、パレットを変えたくなっても直す場所が1箇所で済む。
content設定が消えた
v3で地味に面倒だったのがcontentのパス指定だ。globのパターンを間違えてクラスがパージされる事故は、経験者なら一度はやっていると思う。v4はプロジェクト内のファイルを自動検出するので、うちのサイトでは何も書いていない。.astroファイルの中のクラスも、TypeScriptからclassList.add()しているクラスも、特に設定なしで拾われた。
外部パッケージの中を見せたい場合などは@sourceディレクティブで足せるらしいが、自分のプロジェクトでは必要になったことがないので、そういうものがあるという認識に留めている。
ハマった話: dark:のデフォルトはクラスではなくOS設定
正直にハマった話を書く。うちのサイトにはダークモードのトグルボタンがあって、TypeScriptでdocument.documentElement.classList.toggle('dark')している。v3のdarkMode: 'class'の感覚のまま、dark:bg-slate-900のようなユーティリティと、.dark .glass { ... }のような自作CSSを混ぜて書いていた。
ところがv4のデフォルトでは、dark:バリアントは**.darkクラスではなくprefers-color-scheme: darkメディアクエリ**にコンパイルされる。configが無くなったのでdarkMode: 'class'に相当する指定をどこにも書いておらず、結果として「自作CSSの部分はトグルで切り替わるのに、dark:ユーティリティの部分はOSの外観設定にしか反応しない」という中途半端な状態になっていた。
タチが悪いのは、開発中に気づきにくいことだ。自分の開発環境のOS設定とトグルの状態が一致していると、見た目は正しく切り替わっているように見える。自分はこの記事を書くためにビルド済みCSSをgrepして、dark:系のセレクタが@media (prefers-color-scheme: dark)の中に入っているのを見てようやく確信した。
クラスベースに戻すには、CSSエントリに@custom-variantを1行書く。
@custom-variant dark (&:where(.dark, .dark *));
v3からの移行者向けドキュメントには書いてあるのだが、新規で建てるとconfigを書く工程自体が無いので、この手の「v3ではconfigにあった挙動の分岐」を意識するタイミングが無い。設定ファイルが消えたことの数少ない副作用だと思う。トグル式のダークモードを作るなら、最初にこの1行を入れてから始めるのをおすすめする。
ビルド速度は「速い」というより「意識しなくなった」
v4はビルドエンジンがRust製(Oxide)に書き直されて、公式は大幅な高速化を謳っている。ただ自分のサイトはページ数十枚の小規模サイトなので、「v3なら何秒だったのがv4で何秒になった」という比較は持っていないし、捏造もしない。
実感として言えるのは、開発中にCSSの反映を待ったことが一度も無い、ということだ。クラスを書き換えてブラウザに視線を戻すと変わっている。v3の後期も十分速かったが、少なくとも「Tailwindのビルドが開発のボトルネックになる」という感覚は完全に過去のものになった。
v3から移行する人へ(自分は通っていない道)
繰り返すが自分は新規構築なので、移行の実体験は無い。分かっている範囲だけ書くと、公式が移行ツールを出している。
npx @tailwindcss/upgrade
エントリCSSの@tailwind base; @tailwind components; @tailwind utilities;が@import "tailwindcss";の1行になり、configの中身は@themeへ移す、というのが大きな流れだ。ただ前述のダークモードのように「configの挙動指定がCSSディレクティブに置き換わった」箇所は自動変換だけで済むとは限らないので、移行後の動作確認は省略しない方がいい。
新規プロジェクトなら迷う理由は無いと思う。設定ファイルを書かずに始められて、テーマがCSS変数として自作CSSと共有できて、速度は意識の外に出た。レイアウト自体の組み方はCSS GridとFlexboxの使い分けに書いた内容がv4でもそのまま通用するし、デザインカンプからのコーディングフローはFigmaからコーディングを効率化する話にまとめている。ダークモードの1行だけ、忘れずに。