💨

Tailwind CSS に流動的 Spacing を導入

2021/07/13に公開

はじめに

まず、Tailwind CSS の spacing とは何かについては、公式の Spacing ページ をご覧ください。Tailwind CSS はユーティリティファーストの CSS フレームワークですので、提供する paddingmargin などのサイズは予め決められています。その基となるのが Spacing ページ下部にある Default spacing scale という表です。

Tailwind CSS default spacing scale
Tailwind CSS default spacing scale

Name がサイズ名で、size が実際の値で、pixels がピクセルに換算したときの数値です。この spacing は、paddingmarginwidthheighttopleft などなど、さまざまなプロパティに利用されます。Tailwind CSS を使用したことがある方はご存知だと思いますが、使い方は以下のような感じです。

html
<div class="p-4">...</div> <!-- padding: 1rem; -->
<div class="my-10">...</div> <!-- margin-top: 2.5rem; margin-bottom: 2.5rem; -->
<div class="-mt-5">...</div> <!-- margin-top: -1.25rem; -->
<div class="w-64">...</div> <!-- width: 16rem; -->
<div class="h-32">...</div> <!-- height: 8rem; -->
<div class="top-8">...</div> <!-- top: 2rem; -->

もちろんレスポンシブに対応しているので、以下のような記述をすれば、スクリーンサイズに応じてマージンを変えることができます。

html
<div class="my-2.5 sm:my-5 md:my-6 lg:my-8 xl:my-10">...</div>

このようにブレークポイントごとに段階的にマージンやサイズを変化させることはできますが、場合によっては vw を使ってもっと流動的に変化させたいこともあるでしょう。しかし、デフォルトの spacing ではできません。

JIT (Just-in-Time) モード

Tailwind CSS v2.1 以上であれば JIT モードを利用して vw を使うことができます。JIT モードとは、予め用意されたスタイルではなく、HTML のマークアップ時に必要に応じてスタイルを生成する機能です。以下のように角括弧の中に有効な値を記述すれば、そのスタイルが自動的に生成されます。

html
<div class="my-[3.125vw]">...</div>

上記によって以下の CSS が自動的に生成されます。

css
.my-\[3\.125vw\] {
  margin-top: 3.125vw;
  margin-bottom: 3.125vw;
}

しかも、calc()clamp() などの関数も利用できます。注意点として角括弧の中でスペースをなくし詰めて書く必要があります。

html
<div class="my-[clamp(2rem,calc(2.5vw+1.5rem),3rem)]">...</div>

上記でちゃんと以下の CSS が生成されて、スクリーンサイズに応じて縦方向のマージンが 2rem から 3rem までリニアに変化します。

css
.my-\[clamp\(2rem\2c calc\(2\.5vw\+1\.5rem\)\2c 3rem\)\] {
  margin-top: clamp(2rem,calc(2.5vw + 1.5rem),3rem);
  margin-bottom: clamp(2rem,calc(2.5vw + 1.5rem),3rem);
}

Tailwind CSS の spacing を拡張

JIT モードは、一時的なスタイルであればとても便利な機能ですが、よく利用するものはやはり予め設定しておきたいところです。やり方は簡単で tailwind.config.js 内で spacing を拡張すれば、自動的にさまざまなプロパティでスタイルを生成してくれます。

tailwind.config.js
module.exports = {
  theme: {
    extend: {
      spacing: {
        'vw-10': '3.125vw',
        // ...
      }
    }
  }
}

これだけで、p-vw-10m-vw-10top-vw-10 などが使えるようになります。さらに、-mt-vw-10-top-vw-10 などのネガティブな値もちゃんと使えます。

流動的 spacing の設定値

予め設定する場合は、使いやすい値にしたいところです。Tailwind CSS の default spacing scale みたいに、汎用的に使える流動的 spacing はどのような値にすればよいかについて考えてみます。

rempx のような固定値であれば、極端な話 1px ずつ設定すれば、ほぼすべての値をカバーできますが、vw の場合、1vw2vw のような単純な値だけでなく、calc(2vw + 1rem) のように変化率を変えたい場合も多いと思います。しかし、正直なところすべてのケースをカバーするのは不可能なので、ある程度汎用的であればいいということを目標にします。

結論から言いますと、画面幅が 1280px のときの Tailwind CSS の default spacing scale の値を vw に換算すると、ちょうどいい感じがします。言葉で説明するよりも下図を見たほうがわかりやすいと思います。

あとはこれを下記のように tailwind.config.js に記述していけば大丈夫です。

tailwind.config.js
module.exports = {
  theme: {
    extend: {
      spacing: {
        'vw-1': '0.3125vw',
        'vw-1.5': '0.46875vw',
        'vw-2': '0.625vw',
        // ...
      }
    }
  }
}

これだけでもかなりの数がありますが、こういう流動的な値を指定する場合、ある範囲内でのみ変化するよう最大値と最小値を設定することが多々あると思います。下記のように Tailwind CSS のレスポンシブ機能を利用してもいいんですが、やはり各ブレークポイントでの値を計算するのは面倒くさいです。

<div class="my-5 sm:my-vw-10 lg:my-8">...</div>

ということで、それらをすべて解決するプラグインを作りましたので、続きはそちらを解説いたします。

tailwindcss-fluid-spacing

https://github.com/ixkaito/tailwindcss-fluid-spacing

インストール

まずは npm からプラグインをインストールします。

npm install -D tailwindcss-fluid-spacing
# or
yarn add -D tailwindcss-fluid-spacing

次に tailwind.config.js にプラグインを追加します。

tailwind.config.js
module.exports = {
  theme: {
    // ...
  },
  plugins: [
    require('tailwindcss-fluid-spacing'),
    // ...
  ],
}

これだけで上記設定の流動的 spacing がすべて使えるようになります。

使い方

基本

通常の spacing 同様、paddingmarginwidthheightinset などのコアプラグインに継承されます。各ユーティリティの {size} の前に vw- を挿入してください。

例:

html
<div class="p-vw-8">...</div> <!-- padding: 2.5vw; -->
<div class="mx-vw-16">...</div> <!-- margin-left: 5vw; margin-right: 5vw; -->
<div class="-mt-vw-16">...</div> <!-- margin-top: -5vw; -->
<div class="w-vw-64">...</div> <!-- width: 20vw; -->
<div class="h-vw-32">...</div> <!-- height: 10vw; -->
<div class="gap-vw-10">...</div> <!-- gap: 3.125vw; -->
<div class="top-vw-24">...</div> <!-- top: 7.5vw; -->
<div class="inset-vw-4">...</div> <!-- top: 1.25vw; right: 1.25vw; bottom: 1.25vw; left: 1.25vw; -->
<div class="translate-y-vw-12">...</div> <!-- --tw-translate-y: 3.75vw; transform: var(--tw-transform); -->

レスポンシブ

ほかのユーティリティ同様 {screen}: プレフィックスをつけることができますが、おすすめは tailwindcss-fluid-spacing 独自の -{min|max}@{screen} 記法です。最小値のみ、最大値のみ、最小値と最大値両方の3種類に対応しています。

例:

html
<div class="mt-vw-16-min@sm">...</div> <!-- margin-top: max(5vw, 2rem); -->
<div class="mt-vw-16-max@xl">...</div> <!-- margin-top: min(5vw, 4rem); -->
<div class="mt-vw-16-min@sm-max@xl">...</div> <!-- margin-top: clamp( 2rem, 5vw, 4rem ); -->

上記の例では、vw-16sm スクリーンと xl スクリーンでの値を自動的に計算し、最小値と最大値に適用します。

さらに、ブレークポイントのカスタマイズにも対応しています。

例:

tailwind.config.js
module.exports = {
  theme: {
    extend: {
      screens: {
        800: '800px',
      },
    },
  },
  plugins: [
    require('tailwindcss-fluid-spacing'),
  ],
}
html
<div class="mt-vw-16-max@800">...</div> <!-- margin-top: min(5vw, 2.5rem); -->

このように独自に追加されたブレークポイントも、最小値・最大値の対象として利用できます。

カスタマイズ

プラグイン読み込み時にオプションを渡すことで、生成されるサイズをカスタマイズすることができます。

初期設定を変更

tailwind.config.js
module.exports = {
  theme: {
    // ...
  },
  plugins: [
    require('tailwindcss-fluid-spacing')({
      sizes: [16, 20, 24],
    }),
    // ...
  ],
}

これで {size} として 162024 のみが使えるようになります。例:p-vw-16m-vw-20w-vw-24 など。

設定を拡張

tailwind.config.js
module.exports = {
  theme: {
    // ...
  },
  plugins: [
    require('tailwindcss-fluid-spacing')({
      extend: {
        sizes: [68, 76],
      },
    }),
    // ...
  ],
}

extend の中に入れることで、サイズを追加することができます。これで p-vw-68m-vw-76 などが使えるようになります。

対応表

最後に初期設定のサイズと Tailwind CSS のデフォルトブレークポイントの対応表を載せておきます。

Size Value 320px sm: 640px md: 768px lg: 1024px xl: 1280px 2xl: 1536px
1 0.3125vw 1px 2px 2.4px 3.2px 4px 4.8px
1.5 0.46875vw 1.5px 3px 3.6px 4.8px 6px 7.2px
2 0.625vw 2px 4px 4.8px 6.4px 8px 9.6px
2.5 0.78125vw 2.5px 5px 6px 8px 10px 12px
3 0.9375vw 3px 6px 7.2px 9.6px 12px 14.4px
3.5 1.09375vw 3.5px 7px 8.4px 11.2px 14px 16.8px
4 1.25vw 4px 8px 9.6px 12.8px 16px 19.2px
5 1.5625vw 5px 10px 12px 16px 20px 24px
6 1.875vw 6px 12px 14.4px 19.2px 24px 28.8px
7 2.1875vw 7px 14px 16.8px 22.4px 28px 33.6px
8 2.5vw 8px 16px 19.2px 25.6px 32px 38.4px
9 2.8125vw 9px 18px 21.6px 28.8px 36px 43.2px
10 3.125vw 10px 20px 24px 32px 40px 48px
11 3.4375vw 11px 22px 26.4px 35.2px 44px 52.8px
12 3.75vw 12px 24px 28.8px 38.4px 48px 57.6px
14 4.375vw 14px 28px 33.6px 44.8px 56px 67.2px
16 5vw 16px 32px 38.4px 51.2px 64px 76.8px
20 6.25vw 20px 40px 48px 64px 80px 96px
24 7.5vw 24px 48px 57.6px 76.8px 96px 115.2px
28 8.75vw 28px 56px 67.2px 89.6px 112px 134.4px
32 10vw 32px 64px 76.8px 102.4px 128px 153.6px
36 11.25vw 36px 72px 86.4px 115.2px 144px 172.8px
40 12.5vw 40px 80px 96px 128px 160px 192px
44 13.75vw 44px 88px 105.6px 140.8px 176px 211.2px
48 15vw 48px 96px 115.2px 153.6px 192px 230.4px
52 16.25vw 52px 104px 124.8px 166.4px 208px 249.6px
56 17.5vw 56px 112px 134.4px 179.2px 224px 268.8px
60 18.75vw 60px 120px 144px 192px 240px 288px
64 20vw 64px 128px 153.6px 204.8px 256px 307.2px
72 22.5vw 72px 144px 172.8px 230.4px 288px 345.6px
80 25vw 80px 160px 192px 256px 320px 384px
96 30vw 96px 192px 230.4px 307.2px 384px 460.8px

おわりに

vw を多用するプロジェクトであればぜひ tailwindcss-fluid-spacing を試してみてください。僕自身も実案件で利用しています。それでは、よい Tailwind CSS ライフを。

Discussion