dev TailwindCSS

TailwindCSS fr 単位の使い分け|1frの罠・固定+可変・比率指定 完全ガイド

TailwindCSS fr 単位は CSS Grid で残り領域を比率で配分する単位です。固定+可変、比率指定、minmax(0, 1fr) で長文崩れの罠を回避するテクニックを実例付きで解説します。

TailwindCSS fr 単位の使い分け、できていますか?「grid-cols-2 で2カラムを作ったらサイドが広すぎる」「メインを2倍幅にしたいのに grid-cols-N では実現できない」「1fr 2fr で組んだら長文コンテンツで grid が崩れた」——これらは多くの開発者が任意値構文に踏み込んだ瞬間にハマる落とし穴です。

この記事では、TailwindCSS で fr 単位を使いこなす3つのテクニックを、NG/OK のコードと実際の表示画像を並べながら解説します。

TailwindCSS で grid-cols-2 を使い、サイドバーとメインが50:50の均等割になりサイドが広すぎる例

「サイドバー + メインのレイアウトを grid-cols-2 で書いたけれど、サイドが広すぎる」——そう感じた経験はありませんか?実はこれが今回の1つ目のテクニックの題材です。

私の体験談

その前に、私の体験談を紹介させてください。

今回この記事を執筆するにあたって、公式サイトの Grid Template Columns ページを読んでみたのですが、最初から意図を読み取ることはできず、何度も試していくうちに、ようやく使えるようになったという印象です。

特にテクニック3 の「1fr 2fr で書いた瞬間に長文コンテンツで grid が崩れる罠」は、自分で書いて初めて気づけたものでした。

同じように「公式 docs は読んだけれど、いまひとつ使いこなせない」と感じている方の役に立てれば嬉しいです。

今回紹介する3つのテクニック

TailwindCSS で fr 単位を扱うときに開発者が躓きやすいポイントを、3つに絞って取り上げます。それぞれ「読者がやりがちな誤解 → NGコード → OKコード → 解説 → ポイント」の流れで進めます。コードはすべて Tailwind Play で再現できる形で示します。

テクニック1: 固定 + 可変の組み合わせ

誤解シナリオ:

読者Aさんは、サイドバー + メインの2カラムレイアウトを Tailwind で作りたいと思っています。

  1. 公式ドキュメント(Grid Template Columns - Tailwind CSS)で grid-cols-<number> を見つける
  2. 「2カラムだから grid-cols-2 でいいだろう」と適用
  3. 結果、サイドが広すぎる! メインが狭すぎる!
  4. grid-cols-2 のソースを見ると repeat(2, minmax(0, 1fr))均等割しかできないことに気づく
  5. 「サイドだけ 240px に固定する書き方は?」と探す
  6. 公式 docs の「Using a custom value」セクションで任意値構文の例を発見
  7. [grid-template-columns:240px_1fr] で解決

NGパターン:

<div class="bg-slate-700 p-8">
  <div class="grid grid-cols-2 gap-4">
    <aside class="bg-white rounded-lg p-4">
      <h3 class="font-bold mb-2">サイドバー</h3>
      <ul class="text-sm space-y-1">
        <li>メニュー1</li>
        <li>メニュー2</li>
        <li>メニュー3</li>
      </ul>
    </aside>
    <main class="bg-white rounded-lg p-4">
      <h3 class="font-bold mb-2">メインコンテンツ</h3>
      <p class="text-sm">本文がここに入ります。記事のタイトルや段落、画像などを配置します。</p>
    </main>
  </div>
</div>
TailwindCSS で grid-cols-2 を使い、サイドバーとメインが50:50の均等割になりサイドが広すぎる例

grid-cols-2 は内部的に repeat(2, minmax(0, 1fr)) を生成するため、2列が均等(50% : 50%)になります。サイドの中身が少なくても 50% 取られてしまい、メインが狭くなります。

OKパターン:

<div class="bg-slate-700 p-8">
  <div class="grid grid-cols-[240px_1fr] gap-4">
    <aside class="bg-white rounded-lg p-4">
      <h3 class="font-bold mb-2">サイドバー</h3>
      <ul class="text-sm space-y-1">
        <li>メニュー1</li>
        <li>メニュー2</li>
        <li>メニュー3</li>
      </ul>
    </aside>
    <main class="bg-white rounded-lg p-4">
      <h3 class="font-bold mb-2">メインコンテンツ</h3>
      <p class="text-sm">本文がここに入ります。記事のタイトルや段落、画像などを配置します。</p>
    </main>
  </div>
</div>
TailwindCSS で任意値構文 grid-cols-[240px_1fr] を使い、サイドバーが240px固定、メインが残り全領域に配置された例

[grid-template-columns:240px_1fr] で書くと、1列目は 240px 固定、2列目は 残り全部 になります。

解説:

grid-cols-N は均等割しかできない、という制約を理解することが第一歩です。

ユーティリティ生成される CSSできること
grid-cols-2grid-template-columns: repeat(2, minmax(0, 1fr));2列 均等割 のみ
grid-cols-[240px_1fr]grid-template-columns: 240px 1fr;1列目 240px固定 + 2列目 残り全部

ここで重要なのが 1fr の本質です。

1fr = fractional unit(分数単位)

  • 1fr 単独 → 「残り領域全部」を意味する
  • 240px 1fr240px を引いた残り が 1fr に割り当たる
  • 任意値構文では半角スペースを _(アンダースコア)でエスケープする規則

任意値構文(arbitrary values)は Tailwind の JIT engine(2021-03 導入)で初めて利用可能となり、v3.0(2021-12) で安定版・デフォルト化されました。これにより CSS の表現力をそのまま Tailwind のクラス記法に取り込めるようになっています。

ポイント:

固定幅 + 可変幅の組み合わせを実現したいときは、任意値構文 [grid-template-columns:240px_1fr] を使いましょう。grid-cols-N は均等割専用)

テクニック2: 比率指定(1fr 2fr / 1fr 3fr など)

誤解シナリオ:

読者Bさんは、メイン領域を サイドの2倍幅 にしたいと思っています。

  1. 公式ドキュメント(Grid Template Columns - Tailwind CSS)で grid-cols-N を試す
  2. grid-cols-21 : 1 の均等割になり、メインが2倍にならない
  3. 「比率を変える書き方は?」と探すが、grid-cols-N には比率指定機能がない
  4. テクニック1 で学んだ任意値構文を思い出す → 「pixel で 300px 600px ならどうか?」と試す
  5. 画面幅が変わるたびにレイアウトが崩れる(小さい画面ではみ出し、大きい画面で余白)
  6. 「比率のまま、画面幅に追従させたい…」と困惑
  7. [grid-template-columns:1fr_2fr] で解決

NGパターン:

<div class="bg-slate-700 p-8">
  <div class="grid grid-cols-2 gap-4">
    <aside class="bg-white rounded-lg p-4">
      <h3 class="font-bold mb-2">サイド(1の幅)</h3>
      <p class="text-sm">本来は狭くしたい</p>
    </aside>
    <main class="bg-white rounded-lg p-4">
      <h3 class="font-bold mb-2">メイン(2の幅にしたい)</h3>
      <p class="text-sm">記事本文をたっぷり表示したい</p>
    </main>
  </div>
</div>
TailwindCSS で grid-cols-2 を使い、サイドとメインが1:1の均等割になりメインを2倍にできない例

grid-cols-2 だと 1 : 1 の均等になり、メインを2倍にできません。

OKパターン:

<div class="bg-slate-700 p-8">
  <div class="grid grid-cols-[1fr_2fr] gap-4">
    <aside class="bg-white rounded-lg p-4">
      <h3 class="font-bold mb-2">サイド(1の幅)</h3>
      <p class="text-sm">狭くなった</p>
    </aside>
    <main class="bg-white rounded-lg p-4">
      <h3 class="font-bold mb-2">メイン(2の幅)</h3>
      <p class="text-sm">記事本文をたっぷり表示できる</p>
    </main>
  </div>
</div>
TailwindCSS で任意値構文 grid-cols-[1fr_2fr] を使い、サイドとメインが1:2の比率で配置された例

[grid-template-columns:1fr_2fr] で書くと、サイド : メイン = 1 : 2(およそ 33% : 66%)になります。画面幅が変わっても比率を維持します。

解説:

fr 同士の比率は「残り領域を比率で分配」を意味します。

指定比率概算配分
1fr 1fr1 : 150% : 50%(grid-cols-2 と同じ)
1fr 2fr1 : 233% : 66%
1fr 3fr1 : 325% : 75%
2fr 3fr2 : 340% : 60%
1fr 2fr 1fr1 : 2 : 125% : 50% : 25%(3列も可)

pixel 指定(300px 600px など)では画面幅に追従しないため、レスポンシブ対応では fr 単位が圧倒的に便利です。

fr 単位は CSS Grid Layout Module Level 1(W3C, 2017年勧告候補)で導入された Grid 専用単位で、親要素の gap や固定幅を引いた残り を比率で分配する仕様になっています。

注意:

このテクニックの OK コードは普通のテキストでは問題なく動きますが、長いURLや英数字の連続文字列が入った瞬間にレイアウトが崩れる罠が潜んでいます。次のテクニック3 で扱います。

ポイント:

列幅を比率で指定したいときは、[grid-template-columns:1fr_2fr] のように fr 同士で書きましょう。(pixel 指定では画面幅に追従しない/grid-cols-N では均等割しかできない)

テクニック3: 1fr の罠(minmax(0, 1fr) で回避)

誤解シナリオ:

読者Cさんは、テクニック2 で学んだ [grid-template-columns:1fr_2fr] で比率指定レイアウトを構築しました。

  1. 短いテキストでは問題なく動作 → デプロイ
  2. 後日、メイン領域に 長いURL、コードスニペット、英数字の連続文字列 を表示する必要が出る
  3. 「メイン領域だけ画面から飛び出している!」 とユーザーから報告
  4. DevTools で確認 → 該当列の幅が grid を破壊して画面右端を超えている
  5. 1fr 2fr で比率指定したのに、なぜ崩れる?」と困惑
  6. ふと grid-cols-N のソースを見る → repeat(N, minmax(0, 1fr)) と書いてある
  7. 自分で書いた 1fr と標準ユーティリティの minmax(0, 1fr) は何が違うんだろう?
  8. [grid-template-columns:minmax(0,1fr)_minmax(0,2fr)] で解決

NGパターン:

<div class="bg-slate-700 p-8">
  <div class="grid grid-cols-[1fr_2fr] gap-4">
    <aside class="bg-white rounded-lg p-4">
      <h3 class="font-bold mb-2">サイド</h3>
      <p class="text-sm">メニュー</p>
    </aside>
    <main class="bg-white rounded-lg p-4">
      <h3 class="font-bold mb-2">メイン</h3>
      <p class="text-sm">
        ThisIsAVeryLongUnbreakableContent1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZ
      </p>
    </main>
  </div>
</div>
TailwindCSS で grid-cols-[1fr_2fr] を使うと、メイン列の長文コンテンツが折り返されず grid 全体が画面右端を突破している例

メインの長文が折り返されず、grid 全体が画面右端を突破してはみ出しています。

OKパターン:

<div class="bg-slate-700 p-8">
  <div class="grid grid-cols-[minmax(0,1fr)_minmax(0,2fr)] gap-4">
    <aside class="bg-white rounded-lg p-4">
      <h3 class="font-bold mb-2">サイド</h3>
      <p class="text-sm">メニュー</p>
    </aside>
    <main class="bg-white rounded-lg p-4 break-words">
      <h3 class="font-bold mb-2">メイン</h3>
      <p class="text-sm">
        ThisIsAVeryLongUnbreakableContent1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZ
      </p>
    </main>
  </div>
</div>
TailwindCSS で minmax(0,1fr) と break-words を組み合わせ、メインの長文が折り返されて1:2の比率が維持された例

minmax(0, 1fr) で各列の最小幅を 0 に固定すると、長文も grid 内で折り返され、1 : 2 の比率が維持されます。

解説:

1fr の正体は minmax(auto, 1fr) 相当

  • CSS Grid の 1fr は実装上 minmax(auto, 1fr) と同等の挙動を取ります
  • autoauto-minimum size(自動最小サイズ)と呼ばれ、子要素のコンテンツ最小幅まで track が広がります
  • 折り返せない長文(URL、コード、英数字の連続)が入ると、track の最小幅 = その長文の幅、になります
  • 結果、1fr の比率制約より auto-minimum size が優先され、grid が破綻します

minmax(0, 1fr) で最小幅を 0 に固定

  • minmax(0, 1fr) → 「最小 0、最大 1fr の比率」
  • 最小幅が 0 に固定されるため、コンテンツ長に依存せず比率を維持します
  • 子要素には break-wordstruncate などの折り返し処理を併用すると親切です

なぜ標準 grid-cols-N では問題が起きないか

Tailwind の grid-cols-2grid-cols-3 などは 既に repeat(N, minmax(0, 1fr)) を採用済みです。これは生 CSS の 1fr の罠を回避するためのベストプラクティスを、Tailwind が標準ユーティリティに組み込んでいる設計判断です。実際、v1 系の公式ドキュメントの時点で既に grid-cols-Nrepeat(N, minmax(0, 1fr)) で生成されています。

任意値構文で自分で 1fr を書いた瞬間、生 CSS と同じ罠が顔を出します。

別解: 子要素に min-w-0 を追加

<main class="bg-white rounded-lg p-4 min-w-0 break-words">

子要素に min-width: 0 を指定して、track の auto-minimum size を抑制する古典的な手法もあります。minmax(0, 1fr) と同等の効果です。

ポイント:

任意値構文で 1fr を比率指定で使うときは、minmax(0, 1fr) でラップしましょう。(標準 grid-cols-N は罠回避済み。任意値構文に踏み込むときに罠が顔を出す)

まとめ

TailwindCSS fr 単位を任意値構文で使いこなす3つのテクニックを解説しました。

  • テクニック1: 固定 + 可変は [grid-template-columns:240px_1fr] で書く。grid-cols-N は均等割専用
  • テクニック2: 比率指定は [grid-template-columns:1fr_2fr] で書く。fr 単位は「残り領域を比率で分配」する CSS Grid 専用単位
  • テクニック3: 任意値構文で 1fr を使うときは minmax(0, 1fr) でラップ。1fr = minmax(auto, 1fr) 相当で、auto-minimum size により長文で grid が崩れる罠がある

任意値構文には「アンダースコアでスペースを表現」「minmax(0, 1fr) で罠を回避」など固有のクセがありますが、それを乗り越えれば grid-cols-N の均等割では到達できないレイアウト表現 まで一気に実現できます。これまで grid-cols-N の均等割で詰まっていた方は、ぜひ任意値構文 + fr 単位の組み合わせを試してみてください。

それではまた、別の記事でお会いしましょう。

最初の一歩を踏み出したい方へ

調べても調べても、何が正解かわからない——

WEB系へスキルチェンジするため、TailwindCSSを学び始めた頃の私です。

何から始めればいいのか、見当もつかない。記事を読んでも、情報がバラバラで混乱するばかり。

それでも諦めずに、調べて、手を動かして、試し続けました。

その結果、ようやく見えてきた「最初の一歩」を、この講座にまとめました。

同じ悩みを持つ方へ、最初の一歩を照らすガイドになれば嬉しいです。

👉 TailwindCSSハンズオン講座(無料の導入記事)

[PR]オススメ講座

「実際に作りながら学んでみたい!」という方には、講師「Shin Code」さんのUdemy講座がオススメ!

Shin Codeさんの講座「【Tailwindcss3.0】利用者急増中!作って学ぶ爆速で理解したい人向けのTailwindcss完全入門パック」では、個人用ポートフォリオサイトを作りながらTailwindCSSについて学習することができます。ポートフォリオサイトによくあるナビゲーションやヒーローセクションといった部品をTailwindCSSでどう書けばよいか、講師の方も一緒に手を動かしながら解説してくれています。

TailwindCSS初心者だった私でも一緒に手を動かして写経したら完成したので、個人的にオススメの講座です!

講座の詳細を見る

-dev, TailwindCSS