※Tailwind CSSのチートシート兼プレイグラウンドを作りました。よかったら見ていってください。

Tailwind CSSでレスポンシブデザインを実現するには、ブレイクポイント接頭辞を使う。この接頭辞が付いたクラス名は、接頭辞に対応するスクリーン幅の時にのみ適用される。

デフォルトでは、以下の5つの接頭辞が指定できる。

5つのブレイクポイント接頭辞

公式ドキュメントのレスポンシブデザインのページの冒頭に「ブレイクポイント接頭辞(’Breakpoint prefix’)」と書いてあったので、本記事ではそのまま表記した。

しかし、読み進めると「レスポンシブ修飾子」とも呼ぶようだ。後述の修飾子とひっくるめて理解できるので、後者の方が直感的でわかりやすいかもしれない。

接頭辞 ブレイクポイント 対応するCSS
sm 640px @media (min-width: 640px) { ... }
md 768px @media (min-width: 768px) { ... }
lg 1024px @media (min-width: 1024px) { ... }
xl 1280px @media (min-width: 1280px) { ... }
2xl 1536px @media (min-width: 1536px) { ... }

ブレイクポイントの指定は、class="w-16 md:w-32 lg:w-48"のように行う。

これらの接頭辞は、覚えやすいようで意外に忘れる(歳のせいとは認めない)。頭文字がsmlx2なので、「スマイルx2😀😀」と覚えてみる。

また、それぞれの接頭辞、特にsmmin-widthというメディア特性で指定されている点には注意したい。「smというからには、小さいスクリーンぜんぶサポートしてくれるじゃろ」と誤解するケースが多い。とドキュメントに書いてあった。

すべての範囲で適用したいスタイルは、まず無印のクラス名で指定する。その上で、ブレイクポイント接頭辞を使って各スクリーンサイズに応じたスタイルを連ねていく。これが、Tailwind CSSでレスポンシブデザインを実現する際のセオリーである。

html
<template>
  <!-- Tailwind CSSのコード -->
  <ul class="grid grid-cols-2 sm:grid-cols-3 lg:grid-cols-6 gap-4">
    <li class="p-2 bg-blue-300 sm:bg-blue-400 md:bg-blue-500 lg:bg-blue-600 xl:bg-blue-700 2xl:bg-blue-800 text-slate-900 sm:text-slate-700 md:text-slate-650 lg:text-slate-250 xl:text-slate-200  2xl:text-slate-100  rounded-lg">要素 1</li>
    <li class="p-2 bg-blue-300 sm:bg-blue-400 md:bg-blue-500 lg:bg-blue-600 xl:bg-blue-700 2xl:bg-blue-800 text-slate-900 sm:text-slate-700 md:text-slate-650 lg:text-slate-250 xl:text-slate-200  2xl:text-slate-100  rounded-lg">要素 2</li>
    <li class="p-2 bg-blue-300 sm:bg-blue-400 md:bg-blue-500 lg:bg-blue-600 xl:bg-blue-700 2xl:bg-blue-800 text-slate-900 sm:text-slate-700 md:text-slate-650 lg:text-slate-250 xl:text-slate-200  2xl:text-slate-100  rounded-lg">要素 3</li>
    <li class="p-2 bg-blue-300 sm:bg-blue-400 md:bg-blue-500 lg:bg-blue-600 xl:bg-blue-700 2xl:bg-blue-800 text-slate-900 sm:text-slate-700 md:text-slate-650 lg:text-slate-250 xl:text-slate-200  2xl:text-slate-100  rounded-lg">要素 4</li>
    <li class="p-2 bg-blue-300 sm:bg-blue-400 md:bg-blue-500 lg:bg-blue-600 xl:bg-blue-700 2xl:bg-blue-800 text-slate-900 sm:text-slate-700 md:text-slate-650 lg:text-slate-250 xl:text-slate-200  2xl:text-slate-100  rounded-lg">要素 5</li>
    <li class="p-2 bg-blue-300 sm:bg-blue-400 md:bg-blue-500 lg:bg-blue-600 xl:bg-blue-700 2xl:bg-blue-800 text-slate-900 sm:text-slate-700 md:text-slate-650 lg:text-slate-250 xl:text-slate-200  2xl:text-slate-100  rounded-lg">要素 6</li>
  </ul>
  <!-- ここまで -->

  <script src="https://cdn.tailwindcss.com"></script>
</template>
<div style="width:200px;margin:auto;">
  <input type="range" min="300" max="1920" value="640" /><span>640</span>px
</div>
<div style="overflow:auto;width:100%;">
  <iframe width="641" height="280" style="display:block;margin:auto;"></iframe>
</div>
<script>
  const iframe = document.querySelector("iframe");
  iframe.srcdoc = document.querySelector("template").innerHTML;
  document.querySelector("input").addEventListener("input", (e) => {
    e.srcElement.nextSibling.textContent = e.target.value;
    iframe.width = e.target.value;
  });
</script>

上記のコードでは、iframeに動的にHTMLを埋め込み、その中でCDNを利用してTailwind CSSを使っている。ただし、これはあくまでサンプル用のコードで、本番環境でのCDNの利用は推奨されない(重たいから)。

任意のビルドツールを使ってトランスパイルすべきである。

範囲を絞る修飾子

ブレイクポイント接頭辞は、そのままだとそれ以降のスクリーン幅すべてに適用される。適用範囲を絞りたい時は、max-*という形の修飾子を使って、上限を定める。例えば768px-1280pxまでの範囲で非表示にしたい場合は、sm:max-xl:noneのように記述する。

修飾子の種類は、以下の通り5つの接頭辞と対応している。

修飾子 対応するCSS
max-sm @media not all and (min-width: 640px) { ... }
max-md @media not all and (min-width: 768px) { ... }
max-lg @media not all and (min-width: 1024px) { ... }
max-xl @media not all and (min-width: 1280px) { ... }
max-2xl @media not all and (min-width: 1536px) { ... }

@media not all and (min-width: XXpx)は、「XXpx以上ではない時」に適用、という意味である。

これらは単体でも使える。例えば640px未満でテキストを青くする時などはmax-sm:text-blue-700のように書く。

html
<template>
  <!-- Tailwind CSSのコード -->
  <ul>
    <li class="max-sm:text-blue-200 sm:text-teal-100 max-sm:bg-blue-700 sm:bg-teal-600 p-4">640px未満で青色。</li>
    <li class="md:max-xl:hidden bg-cyan-400 text-cyan-900 p-4">768px-1280pxの範囲で非表示。</li>
  <!-- ここまで -->

  <script src="https://cdn.tailwindcss.com"></script>
</template>
<div style="width:200px;margin:auto;">
  <input type="range" min="300" max="1920" value="640" /><span>640</span>px
</div>
<div style="overflow:auto;width:100%;">
  <iframe width="641" height="150" style="display:block;margin:auto;"></iframe>
</div>
<script>
  const iframe = document.querySelector("iframe");
  iframe.srcdoc = document.querySelector("template").innerHTML;
  document.querySelector("input").addEventListener("input", (e) => {
    e.srcElement.nextSibling.textContent = e.target.value;
    iframe.width = e.target.value;
  });
</script>

ブレイクポイントをカスタムする

ブレイクポイントをカスタムするには、tailwind.config.jstheme.screensプロパティに定義を追加する。

接頭辞の上書き・追加

デフォルトの接頭辞を上書きしたり、追加したり場合は以下のように書く。

js
/** @type {import('tailwindcss').Config} */
module.exports = {
  theme: {
    screens: {
      // ブレイクポイントの上書き
      sm: "576px", //デフォルトは640px
      // => @media (min-width: 576px) { ... }
      md: "960px", //デフォルトは768px
      // => @media (min-width: 960px) { ... }
      xl: "1440px", //デフォルトは1024px
      // => @media (min-width: 1440px) { ... }
      // ブレイクポイントの追加
      "my-break-point": "350px",
      // => @media (min-width: 350px) { ... }
    },
  },
};

screensに指定するオブジェクトは、キーと値のそれぞれが接頭辞とブレークポイントに対応する。上記ではデフォルトと同じ接頭辞名に違う値を指定しているが、接頭辞名自体を変更することもできる。

例えば、smtabletxllaptopなどに変更することができる。

注意したいのは、theme.screensプロパティを上書きすると、既存の設定が丸ごと上書きされる点である。つまり記述していないデフォルトのlg2xlは使えなくなる。

一部のブレイクポイントだけを変更したいときは、theme.screensプロパティではなく、theme.extend.screensプロパティに上書き用の定義を追加する。

js
/** @type {import('tailwindcss').Config} */
module.exports = {
  theme: {
    extend: {
      screens: {
        // ブレイクポイントの上書き
        sm: "576px", //デフォルトは640px
        md: "960px", //デフォルトは768px
        xl: "1440px", //デフォルトは1024px
        // ブレイクポイントの追加
        "my-break-point": "350px",
      },
    },
  },
};

extend以外は同じなので、書き間違いに注意したい。

設定を上書き・追加するデモ

html
<template>
  <p class="my-break-point:max-2xl:bg-yellow-300 my-break-point:max-2xl:text-yellow-800 p-4">350pxから1536pxまで黄色。</p>
  <p class="max-sm:bg-green-500 max-sm:text-green-100 p-4">576px未満で緑色。</p>
  <p class="md:max-xl:hidden bg-red-500 text-red-100 p-4">960px-1440pxの範囲で非表示。</p>
  <script src="https://cdn.tailwindcss.com"></script>
  <script>
    // Tailwind CSSの設定用コード
    tailwind.config = {
      theme: {
        extend: {
          screens: {
            // ブレイクポイントの上書き
            'sm': '576px',//デフォルトは640px
            'md': '960px',//デフォルトは768px
            'xl': '1440px',//デフォルトは1024px
            // ブレイクポイントの追加
            'my-break-point':'350px'
          }
        }
      }
    };
    //ここまで
  </script>
</template>
<div style="width:200px;margin:auto;">
  <input type="range" min="300" max="1920" value="576" /><span>576</span>px
</div>
<div style="overflow:auto;width:100%;">
  <iframe width="577" height="200" style="display:block;margin:auto;"></iframe>
</div>
<script>
  const iframe = document.querySelector("iframe");
  iframe.srcdoc = document.querySelector("template").innerHTML;
  document.querySelector("input").addEventListener("input", (e) => {
    e.srcElement.nextSibling.textContent = e.target.value;
    iframe.width = e.target.value;
  });
</script>

メディア特性をカスタムする

デフォルトでは、メディア特性にmin-widthが使われる。これを変更するオプションもある。

min-widthとmax-widthで範囲を絞る

以下のようにすると、min-widthではなくmax-widthを使ったり、両者を併用して範囲を絞り込んだりできる。

js
module.exports = {
  theme: {
    extend: {
      screens: {
        xs: { max: "639px" },
        // => @media (max-width: 639px) { ... }
        sm: { min: "640px", max: "767px" },
        // => @media (min-width: 640px and max-width: 767px) { ... }
      },
    },
  },
};

1つの接頭辞に複数範囲を設定する

接頭辞名に配列を指定することで、1つの接頭辞に対して複数の範囲を設定できる。

js
/** @type {import('tailwindcss').Config} */
module.exports = {
  theme: {
    extend: {
      screens: {
        md: [{ min: "768px", max: "867px" }, { min: "950px" }],
      },
    },
  },
};

この例では、768px-867pxの範囲でmd接頭辞のクラスが適用される。868-949pxの範囲でsm接頭辞の範囲に戻り、945pxから再びmd接頭辞のクラスが適用される。

メディア特性を任意に指定する

接頭辞に対して、メディア特性を指定することもできる。これには、{'raw':任意のメディア特性}という形式のオブジェクトを修飾子に指定する。

例えば以下のような具合である。

js
/** @type {import('tailwindcss').Config} */
module.exports = {
  theme: {
    extend: {
      screens: {
        land: { raw: "(orientation: landscape)" },
        port: { raw: "(orientation: portlait)" },
      },
    },
  },
};

(orientation: landscape)は横長、(orientation: portlait)は縦長のスクリーンで適用される。単純なレスポンシブデザインを実現したいときに重宝する。

設定を上書き・追加するデモ2

html
<template>
  <p class="xs:w-1/2 bg-red-500 text-red-100 p-2">639pxまで幅50%。</p>
  <p class="sm:w-1/2 bg-blue-500 text-blue-100 p-2">640px-767pxまで幅50%。</p>
  <p class="md:w-1/2 bg-yellow-500 text-yellow-100 p-2">768px-867pxと、950px以上で幅50%。</p>
  <p class="port:w-1/2 land:w-full bg-green-500 text-green-100 p-2">縦長で幅50%、横長で幅100%。</p>
  <script src="https://cdn.tailwindcss.com"></script>
  <script>
    // Tailwind CSSの設定用コード
    tailwind.config = {
      theme: {
        extend: {
          screens: {
            xs: { max: "639px" },
            sm: { min: "640px", max: "767px" },
            md: [{ min: "768px", max: "867px" }, { min: "950px" }],
            land: { raw: "(orientation: landscape)" },
            port: { raw: "(orientation: portrait)" },
          },
        },
      },
    };
    //ここまで
  </script>
</template>
<div style="width:250px;margin:auto;">
  width:<input type="range" min="300" max="1000" value="640" /><span>640</span>px
</div>
<div style="width:250px;margin:auto;">
  height:<input type="range" min="300" max="1000" value="480" /><span>480</span>px
</div>
<div style="overflow:auto;width:100%;">
  <iframe width="641" height="481" style="display:block;margin:auto;"></iframe>
</div>
<script>
  const iframe = document.querySelector("iframe");
  iframe.srcdoc = document.querySelector("template").innerHTML;
  document.querySelectorAll("input")[0].addEventListener("input", (e) => {
    e.srcElement.nextSibling.textContent = e.target.value;
    iframe.width = e.target.value;
  });
  document.querySelectorAll("input")[1].addEventListener("input", (e) => {
    e.srcElement.nextSibling.textContent = e.target.value;
    iframe.height = e.target.value;
  });
</script>

とりあえず、レスポンシブ接頭辞(あるいは修飾子)と、これらメディアクエリ絡みの設定方法の2つを覚えておけば、Tailwind CSSでも問題なくレスポンシブデザインを組めるかと思う。

参考資料