1. なぜ今さら「fluid」なのか? clamp時代のSCSSユーティリティの価値
最近のfluid設計は、ほぼ clamp() 一強です。
font-size: clamp(16px, 4vw, 24px);みたいな書き方は、Smashing Magazine や moderncss.dev をはじめ
いろんな媒体で紹介されています。
ですが、実務でやろうとすると、こうなりがちです。
- デザイナーから「PCでは32px、SPでは20pxくらい」と言われる
- ビューポート幅は… 375〜1440pxくらい?
- じゃあ clamp() の真ん中の式どう計算するの…
- しかも案件ごとに何度も同じ計算を書くのはダルい
ここで生きてくるのが SCSS の
- 変数
- 関数
- ミックスイン
- マップ
を使った fluidユーティリティ群 です。
utils/scss/fluid のようなディレクトリは、おそらく
「数式とロジックを全部カプセル化して、
実装者は @include fluid-font(16px, 24px); みたいに書くだけ」
という世界を目指しているはずです。
2.
utils/scss/fluid
が担っていそうな役割を分解する
パス名から逆算すると、このディレクトリは
- utils …… どこからでも使える汎用ユーティリティ
- scss …… SCSS専用
- fluid …… fluid(流体)なスケールを扱う一式
という位置付けになっているはずです。
中身として典型的にありそうなのは、例えば以下のような構成です。
- _variables.scss
- fluid設計で使うデフォルト値(最小/最大vwなど)
- _functions.scss
- fluid() みたいな、値を返す関数
- _mixins.scss
- fluid-font(), fluid-space() など、プロパティをまとめて吐くミックスイン
- _index.scss or _fluid.scss
- 上記をまとめて @forward / @use するための入口
実際のファイル名は違う可能性がありますが、
「fluidディレクトリとして切り出している」という時点で、
ある程度しっかり設計されたユーティリティ群 である可能性が高いです。
3. 一般的なfluidユーティリティの構成イメージ
では、ここからは
「もし自分が utils/scss/fluid を書くならどう構成するか」
という観点で、かなり現実的な実装像を組み立てていきます。
3-1. まずは前提となる設定値
よくあるのが「プロジェクトのデフォルト」として
- ビューポートの最小幅
- ビューポートの最大幅
- 最小フォントサイズ / 最大フォントサイズの基準値
などを変数として定義するパターンです。
// fluid/_variables.scss
$fluid-min-vw: 375; // SPベース
$fluid-max-vw: 1440; // PCの想定幅
// clampの汎用fallback等に使うベースサイズ
$fluid-base-font-size: 16px;こうしておくと、
- 案件A:375〜1440px
- 案件B:360〜1280px
のように条件が違っても、
変数だけ差し替えれば同じ関数・ミックスインが再利用できます。
3-2. 中心となる
fluid()
関数のイメージ
fluid系ユーティリティの核になるのは、
fluid($min, $max, $min-vw: $fluid-min-vw, $max-vw: $fluid-max-vw)のような関数です。
この関数が返すのは、だいたい次のどちらかです。
- clamp() を返す
- calc() と vw を組み合わせた文字列を返す
最近は1の clamp() ベースが主流です。
擬似コード的には、こんな感じのイメージです。
@function fluid($min, $max, $min-vw: $fluid-min-vw, $max-vw: $fluid-max-vw) {
// 単位チェックやエラー処理を挟んだ上で…
$slope: ($max - $min) / ($max-vw - $min-vw); // 傾き
$intercept: $min - $slope * $min-vw; // 切片
// clamp(
// 最小値,
// (vwに対する傾き * 100vw) + 切片,
// 最大値
// )
@return clamp(
$min,
#{$slope * 100}vw + #{$intercept}px,
$max
);
}実際は単位を px に固定せず、rem ベースで扱ったり、
ひと手間かけて unitless 変換したりしますが、考え方はだいたいこんな感じです。
3-3. 関数を包むミックスインたち
関数ができたら、あとは用途ごとに薄くラップしてあげると使いやすくなります。
たとえば:
- fluid-font($min, $max, …) → font-size 用
- fluid-space($property, $min, $max, …) → margin, padding, gap など任意プロパティに使える
- fluid-width($min, $max, …) → width / max-width / min-width 用
例:
// fluid/_mixins.scss
@use "variables" as *;
@use "functions" as *;
// font-size専用
@mixin fluid-font($min, $max, $min-vw: $fluid-min-vw, $max-vw: $fluid-max-vw) {
font-size: $min;
font-size: fluid($min, $max, $min-vw, $max-vw);
}
// 任意プロパティ用
@mixin fluid-space(
$property,
$min,
$max,
$min-vw: $fluid-min-vw,
$max-vw: $fluid-max-vw
) {
#{$property}: $min;
#{$property}: fluid($min, $max, $min-vw, $max-vw);
}
こうしておくと、コンポーネント側では
.title {
@include fluid-font(18px, 28px);
}
.section {
@include fluid-space(padding-inline, 16px, 40px);
}のように、かなり読みやすい形で使えます。
4. 一番よく使うのはこれ:
fluid()
関数と
fluid-size()
ミックスイン
ここからは、実務でよく使うであろう
「基本の使い方」をサンプルコードつきで整理していきます。
4-1. タイポグラフィ用
fluid-font()
見出しまわりでの典型的な使い方はこんな感じです。
// _typography.scss
@use "../utils/scss/fluid" as fluid;
:root {
// fallbackとして全体の基準を定義
font-size: 16px;
}
h1 {
@include fluid.fluid-font(28px, 40px);
line-height: 1.3;
}
h2 {
@include fluid.fluid-font(24px, 32px);
line-height: 1.4;
}
h3 {
@include fluid.fluid-font(20px, 28px);
line-height: 1.5;
}
コンパイル後のイメージは:
h1 {
font-size: 28px;
font-size: clamp(28px, 3.5vw + 10px, 40px);
line-height: 1.3;
}のような形になります(式はあくまで例)。
- 小さなSPでは 28px からスタート
- ビューポートが広がるに従って自然に大きくなり
- PCで 40px に到達したらそれ以上は大きくならない
という挙動です。
4-2. 余白用
fluid-space()
余白もfluid化しておくと、
SPでもPCでも「ちょうどいい余白感」を保ちやすくなります。
.section {
@include fluid-space(padding-block, 40px, 80px);
@include fluid-space(padding-inline, 16px, 64px);
}このようなユーティリティを持っておくと、
- section間の余白
- カードのインナー余白
- カラム間の gap
などを統一感のある設計で動かせるようになります。
4-3. コンポーネント幅用
fluid-width()
ヒーローエリアのタイトルの行幅なども fluid にしておくと
PCだけやたら長くなってしまう問題を避けられます。
.hero-title {
@include fluid-width(260px, 720px);
}- SPではそこまで幅を取らず
- PCでは適度に広がる
という挙動を、メディアクエリを書かずに実現できます。
5. 実務での使い方サンプル
ここからは、もう少し実務寄りのコード例をまとめておきます。
5-1. WordPress + ブロックエディタ用のタイポグラフィ
WordPress案件の場合、
「ブロックエディタの見出しとフロント側の見出しを合わせたい」
というニーズがよく出てきます。
SCSS側でfluidを使いつつ、エディタ用CSSにも同じミックスインを使えば
かなり楽に運用できます。
// theme/scss/_editor.scss
@use "../utils/scss/fluid" as fluid;
.editor-styles-wrapper {
h1 {
@include fluid.fluid-font(26px, 38px);
}
h2 {
@include fluid.fluid-font(22px, 32px);
}
}フロント用の style.css 側でも 全く同じミックスインを呼べば、
エディタとフロントでズレない設計になります。
5-2. 工数削減用のマップ設計
さらに踏み込んで、「タイポスケール全部をマップ化」しておき、
ループで吐き出すパターンもよくあります。
$fluid-type-scale: (
"h1": (min: 28px, max: 40px),
"h2": (min: 24px, max: 32px),
"h3": (min: 20px, max: 28px),
"body": (min: 14px, max: 16px)
);
@each $name, $sizes in $fluid-type-scale {
.u-fluid-#{$name} {
@include fluid.fluid-font(map-get($sizes, min), map-get($sizes, max));
}
}
これで、HTML側では
<h2 class="u-fluid-h2">見出し</h2>
<p class="u-fluid-body">本文テキスト...</p>のように、ユーティリティクラスとしても使えるようになります。
5-3. ACF+カスタムブロックとの組み合わせ
ACFブロックやカスタムブロックで
「タイトル・リード・ボタン付きのカード」をよく作る場合も、
fluidユーティリティはかなり役立ちます。
.block-hero-card {
.block-hero-card__title {
@include fluid.fluid-font(24px, 34px);
}
.block-hero-card__lead {
@include fluid.fluid-font(16px, 20px);
}
.block-hero-card__btn {
@include fluid.fluid-font(14px, 16px);
@include fluid.fluid-space(padding-inline, 16px, 24px);
}
}ブロックが増えても、「数字を変えるだけ」で済むのが地味に効きます。
6. clampベースのfluid設計をSCSSで包むメリット
「いや、素のCSSで clamp() 直書きすればよくない?」
という気持ちも分かります。
が、実務では SCSSラップのメリットがかなり大きいです。
6-1. 数字遊びを関数に押し込める
clamp() を毎回手で組み立てると、
どうしてもこういう地味なストレスが溜まります。
- 4つの数字を渡す → min font、max font、min vw、max vw
- 傾きと切片の計算が地味に面倒
- 単位の整合性も気にする必要がある
この「計算どこかに閉じ込めたい欲」を
きれいに満たしてくれるのが fluid() 関数です。
6-2. プロジェクト内のバラつきを抑えられる
チーム開発でありがちなのが、
- 人によって clamp() の書き方や考え方がバラバラ
- ある箇所は375〜1440、別の箇所は320〜1024で計算されている
- remにする人、pxのままの人
という「何となく揃ってない」状態です。
SCSSユーティリティとして
- デフォルトのmin/max幅
- 単位の扱い
- 計算方法
を固定化してしまえば、
「この案件のfluidは、基本全部この関数で出す」
とルール化しやすくなります。
6-3. 古いブラウザへのフォールバックも一括管理
IEを完全に切り捨てられる案件は増えましたが、
業種によっては「古いタブレットが現役」というケースもあります。
fluid() 関数の内部で
- clamp() を返す
- ついでに先に font-size: $min; を出力しておく
といった工夫をしておけば、
@mixin fluid-font(...) {
font-size: $min; // ここが古いブラウザ用のフォールバック
font-size: fluid(...); // clampを返す
}のように「古いブラウザは固定サイズ」という安全な挙動にできます。
7. よくあるハマりポイントとガードの入れ方
fluidユーティリティを書く時に
やっておくと幸せになれる防御テクをいくつか。
7-1. 単位の混在チェック
よくあるミス:
@include fluid-font(16px, 2rem); // minとmaxの単位が違うこれを防ぐには、関数内で unit() を使ってチェックし
違っていたら @error を投げるのが王道です。
@function fluid($min, $max, $min-vw: $fluid-min-vw, $max-vw: $fluid-max-vw) {
@if unit($min) != unit($max) {
@error "fluid(): $min と $max の単位は揃えてください。";
}
// 以降、計算処理...
}ビルド時にエラーが出るので、
本番で「なんか変だけど原因が分からない」という事態を避けられます。
7-2. min > max の逆転
これもありがちです。
@include fluid-font(32px, 18px); // 逆これも @if $min > $max { @error … } で潰せます。
7-3. 極端なmin/max幅
ビューポート幅に対して
- 極端に狭い
- 極端に広い
数値を設定してしまうと、
想定どおりの挙動にならないことがあります。
$fluid-min-vw / $fluid-max-vw を変数化しておき、
プロジェクトの最初にチームで決めておくと事故りにくいです。
8. WordPress案件への導入パターン
実務フロントエンド目線でいうと、
utils/scss/fluid は以下のように組み込むのが定番です。
8-1. SCSS構成に組み込む
例:
scss/
utils/
_variables.scss
_mixins.scss
_functions.scss
fluid/
_variables.scss
_functions.scss
_mixins.scss
_index.scss
base/
_reset.scss
_typography.scss
components/
_buttons.scss
_cards.scss
pages/
_front-page.scss
_single.scss
style.scss@use "utils/fluid" as fluid;しておき、あとは各所で fluid.fluid-font() を呼ぶイメージです。
8-2. ブロックテーマ(FSE)との併用
FSEの場合、
- theme.json 側で基本のtypographyを定義
- SCSS側で「特定ブロックだけfluidにする」
というハイブリッド運用もよくあります。
theme.json の値を基準にして
SCSS内のfluidのmin/maxを決める、といった設計も可能です。
8-3. メンテ時のメリット
あとから
- 「全体的にPCの文字ちょっと大きくして」
- 「SP時の余白を気持ち減らしたい」
などの要望が来たとき、
$fluid-min-vw / $fluid-max-vw や
$fluid-type-scale のマップを書き換えるだけで
一括調整できるのはかなり強力です。
9. 一緒に押さえておくと強い関連トピックと学習リソース
最後に、この fluid ユーティリティを理解した上で
一緒に押さえておくと強いトピックと、参考になる外部記事をいくつか挙げておきます。
9-1. clampの数式をちゃんと理解する
- clamp(最小値, 好ましい値, 最大値) の「好ましい値」に vw と rem をどう組み合わせるか
- 任意のビューポート幅に対して 「この時にこのフォントサイズ」となるように式を立てる方法
は、Smashing Magazine の記事が非常に丁寧です。
9-2. Sassでのタイプスケール生成
moderncss.dev の記事では、
Sassでタイプスケールやfluid typographyを生成する方法が
かなり具体的に紹介されています。
utils/scss/fluid のようなユーティリティを書くときも、
ここで紹介されている「マップ+ループ」の考え方がそのまま応用できます。
9-3. container queries × fluidのこれから
今後は @container と
コンテナクエリ系の単位(cqw など)と組み合わせることで、
「ビューポート幅ではなく、
親コンテナの幅に応じてfluidに動く」
設計も主流になっていきます。
今書いているfluidユーティリティも、
- まずはビューポートベース
- 将来的にコンテナベースに移行可能な抽象度
で作っておくと長生きしやすいです。
まとめ:
utils/scss/fluid
は「デザインと実装の橋渡し」をしてくれる
今回、GitHub上の実ファイルはツールの制約で中身を直接読めませんでしたが、
- ディレクトリ名
- 一般的なfluidユーティリティの設計
- clampを使った現代的なfluid実装のトレンド
から逆算すると、utils/scss/fluid はおそらく
「デザイナーがくれたpx指定を、
自然なfluid挙動に変換してくれるSCSSの小さな頭脳」
のような役割を担っているはずです。
もしあなたの案件でも
- 画面幅ごとのフォントサイズ指定が多い
- 余白やコンテナ幅の調整が毎回手作業
- clampを書きたくない
という状況があるなら、
ここで紹介したような構成をベースに
自分専用の utils/scss/fluid を作ってみる価値はかなり高いと思います。

