🍃

Tailwind CSS v4のカスタムユーティリティでgrid-template-areasを使う

2025/02/09に公開

はじめに

Tailwind CSS v4では、tailwind.config.tsで行っていた設定の多くがCSSファイルで行えるようになりました。
これにより、比較的シンプルなカスタムユーティリティの登録がより簡単になりました。

カスタムユーティリティの追加

grid-template-areasgrid-area 用のユーティリティクラスを追加します。

@utility grid-areas-* {
  grid-template-areas: --value([\*]);
}

@utility grid-area-* {
  grid-area: --value([\*]);
}

任意の値を受け取るには --value([{type}]) と書けばよいのですが、肝心の {type} の定義がドキュメント上で見つけられず、mdn のシンタックスにある string を適当に指定してみたのですがうまくいかず、ソースコードを眺めていても適当なタイプがなさそうだったので --value([*]) で受け取るようにします。

https://github.com/tailwindlabs/tailwindcss/blob/d684733d804a0b8951d13c94fe27350271e076b6/packages/tailwindcss/src/utils/infer-data-type.ts#L5-L22

ちなみにドキュメントでは --value([*]) となっているのですが、biomeのエラーが出てしまうので * の前にバックスラッシュをつけています。
(あっているかは分かりません)

https://x.com/achamaromi/status/1887491627352265053

テーマの設定

カスタムユーティリティが登録できたので grid-template-areas grid-area はそれぞれ grid-areas-[] grid-area-[] で任意の値を指定してスタイルを当てることができるようになりました。

テーマでレイアウトを設定しておくことでテーマの中から選択して使用することができます。
エディタにTailwindの拡張をいれている場合はコード補完も効くため入力も簡単になります。

@theme {
  /* biome-ignore format: */
  --grid-areas-layout1:
    "header header header"
    "nav nav nav"
    "main main main"
    "footer footer footer";

  /* biome-ignore format: */
  --grid-areas-layout2:
    "header header header"
    "nav main main"
    "nav main main"
    "footer footer footer";

  --grid-area-header: header;
  --grid-area-nav: nav;
  --grid-area-main: main;
  --grid-area-footer: footer;
}

@utility grid-areas-* {
  grid-template-areas: --value([\*]);
  grid-template-areas: --value(--grid-areas-\*);
}

@utility grid-area-* {
  grid-area: --value([\*]);
  grid-area: --value(--grid-area-\*);
}

テーマで指定した値を使うには --value({--theme}-\*) と書きます。
--value([{type}]) と並べて書くことで、いずれか一致する方が適用されます。

使い方

①任意の値で指定

<div className="grid-areas-['header_header_header''nav_nav_nav''main_main_main''footer_footer_footer']
md:grid-areas-['header_header_header''nav_main_main''nav_main_main''footer_footer_footer']
grid grid-cols-3 grid-rows-4 gap-1 *:p-5">
  <header className="grid-area-[header]">header</header>
  <nav className="grid-area-[nav]">nav</nav>
  <main className="grid-area-[main]">main</main>
  <footer className="grid-area-[footer]">footer</footer>
</div>

②テーマで指定

<div className="grid-areas-layout1 md:grid-areas-layout2 grid
grid-cols-3 grid-rows-4 gap-1 *:p-5">
  <header className="grid-area-header">header</header>
  <nav className="grid-area-nav">nav</nav>
  <main className="grid-area-main">main</main>
  <footer className="grid-area-footer">footer</footer>
</div>

③カスタムプロパティで指定

const layout = {
  "--layout1": `
    "header header header"
    "nav nav nav"
    "main main main"
    "footer footer footer"
  `,
  "--layout2": `
    "header header header"
    "nav main main"
    "nav main main"
    "footer footer footer"
  `,
} as React.CSSProperties;

<div
className="grid-areas-(--layout1) md:grid-areas-(--layout2) grid
grid-cols-3 grid-rows-4 gap-1 *:p-5" style={layout}>
  <header className="grid-area-[header]">header</header>
  <nav className="grid-area-[nav]">nav</nav>
  <main className="grid-area-[main]">main</main>
  <footer className="grid-area-[footer]">footer</footer>
</div>

今回作ったもの

https://github.com/achamaro/tailwindcss4-grid-template-areas

Discussion