Go back

Tailwind v4 へ移行した — Astro 7 後の CSS 刷新と Scraps UI の整備

Posted on:2026-06-24

Astro 7 へのアップグレードでは、表示崩れを避けるため Tailwind v3 + PostCSS の暫定構成のままにしました。次のタスクとして Issue #35 で挙げていた Tailwind v4 + @tailwindcss/vite への移行に着手し、あわせて Scraps ページのヘッダー周りも整えました。

背景

Astro 7 移行時は @astrojs/tailwind が非対応だったため、次の構成で凌いでいました。

項目 暫定構成(v3)
Tailwind v3.4
統合 postcss.config.cjs 経由
設定 tailwind.config.cjswithOpacity + skin-* テーマ)
Typography @tailwindcss/typography

Astro 7 本体が落ち着いたので、公式推奨の Tailwind v4 + Vite プラグイン に切り替えるタイミングと判断しました。

Tailwind v4 移行でやったこと

ブランチ issue-35/tailwind-v4 で作業しました。

1. 依存関係と Astro 設定

pnpm add tailwindcss@^4 @tailwindcss/vite
pnpm add -D @tailwindcss/typography@latest
pnpm remove autoprefixer postcss

astro.config.mjsvite.plugins@tailwindcss/vite を登録します。PostCSS 経由の Tailwind 設定は削除しました。

2. CSS-first 設定へ移植

tailwind.config.cjs を廃止し、src/styles/base.css に集約しました。

@import "tailwindcss";
@plugin "@tailwindcss/typography";

@theme {
  --color-skin-base: var(--color-text-base);
  --color-skin-accent: var(--color-accent);
  /* ... */
}

テーマ切替用の CSS 変数は、v4 の /50 不透明度修飾子と相性がよい hex 値(例: #fbfefb)へ変換しました。RGB チャンネル形式(251, 254, 251)のままだと color-mix() ベースの修飾子が効きにくいためです。

@theme inline は使わない点がポイントです。ビルド時に色が固定され、ダークモード切替が効かなくなります。

3. Astro の scoped style 対応

Tailwind v4 では、Astro コンポーネントの <style>@apply がメイン CSS と分離されます。Header.astro など 12 ファイル<style> 先頭に @reference "../styles/base.css" を追加しました。

4. 削除したファイル

  • postcss.config.cjs
  • tailwind.config.cjs

移行後にハマった表示崩れ

ビルドは通ったものの、目視で次の問題が出ました。

すべての a タグに枠線が付く

v3 では outline-2 outline-skin-accent を常時指定していても、フォーカス時以外は見えませんでした。v4 では 常に 2px のアウトライン が描画され、リンク全体がボーダー付きに見えました。

対処は、通常時 outline-none:focus-visible のときだけアウトラインを出す形に変更することです。

a {
  @apply focus-visible:outline-skin-accent outline-none
  outline-offset-1 focus-visible:no-underline
  focus-visible:outline-dashed focus-visible:outline-2;
}

ヘッダーナビが縦並びになる

Header.astro の scoped CSS で nav ul { display: grid } を指定していたため、HTML 側の sm:flex より 詳細度が高く、640px 以上でもグリッドのままになっていました。

nav ulsm:flex sm:flex-row を明示的に足して解消しました。Tailwind v4 移行後は、scoped CSS とユーティリティクラスの優先関係を再確認する必要がありました。

Scraps ページの UI 整備

Tailwind 移行と並行して、Scraps まわりも直しました。

ページ 変更
/scraps 一覧 サイト共通の Header / Footer を追加。Open / Archive タブはタイトル右側、サイズを小さく
/scraps/[slug] 詳細 同上
/scraps/[slug]/edit 編集 同上

以前の Scraps 一覧はヘッダーなしで本文だけが表示され、サイトの他ページと体験がずれていました。一覧・詳細・編集でナビゲーションを揃え、activeNav="scraps" で現在地が分かるようにしています。

Scraps のローカル開発メモ

移行作業中、「スクラップの取得に失敗しました」でハマりました。原因は Astro サイト(pnpm dev)だけ起動していて、Scrap API Worker が動いていなかったことです。

Scraps はブラウザから PUBLIC_SCRAP_API_BASE(ローカルでは http://127.0.0.1:8787)へ fetch するため、2 プロセス が必要です。

ターミナル A — Scrap API

# 初回のみ
pnpm exec wrangler d1 execute redamoon-scrap --local \
  --file=workers/scrap-api/schema.sql --config wrangler.toml

pnpm exec wrangler dev --config wrangler.toml --port 8787

ターミナル B — サイト本体

pnpm dev

.env の例:

PUBLIC_SCRAP_API_BASE=http://127.0.0.1:8787
PUBLIC_SCRAP_ADMIN_ENABLED=true

管理 UI を使う場合は、Worker 用に .dev.varsADMIN_TOKEN も置きます。/scraps/login のパスワードはこの値と同じです。

注意: wrangler dev だけ実行すると、dist/server/wrangler.json(Astro サイト)を拾うことがあります。Scrap API を起動するときは必ず --config wrangler.toml を付けてください。

まとめ

  • Astro 7 移行時に見送った Tailwind v4 + @tailwindcss/vite を Issue #35 として対応した
  • withOpacity + JS 設定を @theme + hex 変数へ移植。postcss.config.cjs / tailwind.config.cjs は削除
  • v4 固有の表示崩れ(リンクのアウトライン、ヘッダーの flex/grid 競合)を個別に修正
  • Scraps 一覧・詳細・編集に共通ヘッダーを追加
  • Scraps のローカル開発は サイト + scrap-api Worker の 2 本立て が必須

次は README の Tailwind 記述更新や、Scraps 配下の /scraps/media など残りページへのヘッダー適用を進めたいと思います。