WithCodeMedia-1-pc
previous arrowprevious arrow
next arrownext arrow

WithCodeMedia-1-sp
previous arrowprevious arrow
next arrownext arrow

【2026年版】CSS calc()の使い方完全ガイド|単位混在・レスポンシブ計算をコピペで

CSSでレイアウトを組んでいると、「サイドバーが240pxあるから、メインコンテンツは残りの幅にしたい」「ヘッダーが60pxあるから、コンテンツエリアは100vhから60px引いた高さにしたい」という場面が必ず来ます。これを手計算でpxに落とし込もうとすると、画面幅が変わるたびに値が崩れてしまいます。

そこで活躍するのがCSS calc()です。calc()を使えば、異なる単位(%とpx、vwとremなど)を混在させた計算式をCSSのプロパティ値として直接書くことができます。ブラウザがレンダリング時に計算してくれるため、JavaScriptに頼らずレスポンシブなレイアウトを実現できます。

この記事では、calc()の基本構文から四則演算のルール、実践的なレイアウトテクニック、CSS変数(var)との組み合わせ、さらにclamp()・min()・max()との使い分けまでを網羅します。コピペで動くコード例を中心に、初心者から中級者まで実務で使える知識を身につけましょう。

目次

calc()とは何か・なぜ必要か

calc()の役割

calc()はCSS Values and Units Module Level 4で定義されているCSS計算関数です。プロパティの値として数式を記述でき、ブラウザが実際の描画時に計算結果を適用します。対応しているプロパティはwidth・height・margin・padding・top・left・font-size・line-height・grid-template-columnsなど、長さや数値を受け取るほぼすべてのプロパティです。

2026年現在、すべての主要ブラウザ(Chrome・Firefox・Safari・Edge)で完全サポートされており、ベンダープレフィックスは不要です。IE11のサポートも終了しているため、実務で安心して使えます。

calc()がない時代の苦労

calc()が普及する前は、異なる単位を混ぜた計算はJavaScriptで行うか、親要素を入れ子にして相対値を重ねるなどの工夫が必要でした。たとえば「100%の幅から32pxを引く」という表現はCSSだけでは不可能で、box-sizingで解決できない場面では複雑なDOM構造を強いられていました。calc()はその問題をシンプルに解決します。

基本構文と書き方のルール

基本構文

calc()の構文はシンプルです。括弧の中に計算式を書くだけです。

/* 基本構文 */
property: calc(式);

/* 例 */
width: calc(100% - 240px);
height: calc(100vh - 60px);
font-size: calc(1rem + 0.5vw);
padding: calc(8px * 2);

calc()は四則演算(加算・減算・乗算・除算)をサポートしており、CSSで有効な数値・長さ・角度・時間・パーセンテージ・解像度などの値を組み合わせられます。

演算子の前後にスペースが必須——最も多いエラーの原因

calc()で最もよくある間違いが、+(加算)と-(減算)の前後にスペースを入れ忘れることです。これはCSSの仕様上の必須ルールで、スペースがないと正しく解析されず、プロパティ全体が無効になります。

/* NG: + と - の前後にスペースがない */
width: calc(100%-240px);   /* 無効 */
width: calc(100% -240px);  /* 無効(右側のスペースだけでも不可) */
width: calc(100%- 240px);  /* 無効(左側のスペースだけでも不可) */

/* OK: + と - の前後に必ずスペースを入れる */
width: calc(100% - 240px); /* 有効 */
height: calc(100vh + 10px); /* 有効 */

一方で*(乗算)と/(除算)は前後のスペースが任意です。ただし可読性のためにスペースを入れる習慣をつけると、+ と – と書き方が統一されてミスが減ります。

/* * と / はスペースなしでも動作するが、統一のためスペース推奨 */
width: calc(100% / 3);
padding: calc(8px * 2);

単位のルール

calc()の中では単位の種類ごとに演算の制約があります。

  • 加算・減算:両辺が同じ単位の型(長さ同士、角度同士など)でなければならない。ただし異なる長さ単位(pxとvwなど)は同じ型なのでOK。
  • 乗算:どちらか一方が数値(単位なし)でなければならない。
  • 除算:右辺が数値(単位なし)でなければならない。
/* OK: 異なる長さ単位の加減算 */
width: calc(50% + 20px);
font-size: calc(1rem + 0.5vw);

/* OK: 乗算は片方が数値 */
padding: calc(1rem * 1.5);

/* OK: 除算は右辺が数値 */
width: calc(100% / 4);

/* NG: 両方に単位がある乗算 */
width: calc(10px * 10px); /* 無効 */

/* NG: 右辺に単位がある除算 */
width: calc(100% / 10px); /* 無効 */

四則演算の使い方

加算(+)と減算(-)

加算と減算はレイアウトの「引き算」「積み上げ」に使います。もっとも使用頻度が高い演算です。

.main-content {
  /* サイドバー240px + ガター20px を差し引いたメイン幅 */
  width: calc(100% - 260px);
}

.hero {
  /* ヘッダー高60pxを引いたファーストビュー高さ */
  min-height: calc(100vh - 60px);
}

.card {
  /* 上下パディング合計32pxに加えてボーダー2px×2を足した高さ */
  height: calc(200px + 32px + 4px);
}

乗算(*)

乗算は倍率計算やベースユニットからの比率計算に使います。

.section {
  /* 基準値8pxの3倍 = 24px */
  padding: calc(8px * 3);
}

.text-large {
  /* 基本フォントサイズの1.5倍 */
  font-size: calc(1rem * 1.5);
}

.overlay {
  /* 画面幅の0.8倍(80%と同じ効果だが計算上の意図を明示) */
  width: calc(100vw * 0.8);
}

除算(/)

除算は均等分割やレイアウトグリッドの計算でよく使います。

.grid-item {
  /* 3等分 */
  width: calc(100% / 3);
}

.column {
  /* 4等分から左右マージン計算を引く */
  width: calc(100% / 4 - 16px);
}

演算の優先順位

calc()内での演算の優先順位は通常の算数と同じです。* と / は + と – より先に評価されます。優先順位を明示したい場合は括弧でグルーピングできます(ただしネストのcalc()とは別物)。

/* * が先に計算される: (2 * 20px) = 40px を 100% から引く */
width: calc(100% - 2 * 20px);

/* 括弧で明示的にグルーピング */
width: calc((100% - 40px) / 3);

異なる単位を混在させる——calc()の最大の強み

%とpxの混在

calc()最大の利点は異なる単位の混在です。純粋なCSSでは「親要素の50%からさらに20px引いた幅」を1つのプロパティ値で表現できませんでしたが、calc()なら一行で書けます。

.sidebar-layout {
  display: flex;
}

.sidebar {
  width: 240px;
  flex-shrink: 0;
}

.main {
  /* 親幅から固定サイドバーと余白を引く */
  width: calc(100% - 240px - 32px);
}

vwとpxの混在(可変フォントサイズ)

vw(ビューポート幅の1%)とremを組み合わせることで、画面幅に連動しながらも最小サイズを確保したフォントサイズを実現できます。これはレスポンシブタイポグラフィの基本テクニックです。

.responsive-heading {
  /* 基本1remに画面幅の1%を加算。画面が広いほど大きくなる */
  font-size: calc(1rem + 1vw);
}

.fluid-body {
  /* 最小14px相当 + 画面幅依存の追加量 */
  font-size: calc(0.875rem + 0.25vw);
}

vhと固定値の混在(フルスクリーンレイアウト)

固定ヘッダーの下にコンテンツエリアをぴったりフィットさせるケースは実務で頻出です。

:root {
  --header-height: 60px;
}

header {
  position: fixed;
  top: 0;
  left: 0;
  width: 100%;
  height: var(--header-height);
  background: #fff;
  z-index: 100;
}

.page-content {
  /* ヘッダー高を引いてスクロールなしで画面内に収める */
  min-height: calc(100vh - var(--header-height));
  margin-top: var(--header-height);
  overflow-y: auto;
}

実践:よく使われるレイアウトパターン

サイドバー付きの可変メインコンテンツ幅

2カラムレイアウトで片側が固定幅、もう片側が残りの幅を取るパターンです。Flexboxと組み合わせると堅牢なレイアウトになります。

<div class="layout">
  <aside class="sidebar">サイドバー</aside>
  <main class="main">メインコンテンツ</main>
</div>
.layout {
  display: flex;
  gap: 32px;
  max-width: 1200px;
  margin: 0 auto;
  padding: 0 24px;
}

.sidebar {
  width: 260px;
  flex-shrink: 0;
}

.main {
  /* 親幅 - サイドバー幅 - gap分 - 左右パディング分 */
  width: calc(100% - 260px - 32px);
  min-width: 0; /* Flexboxのオーバーフロー対策 */
}

@media (max-width: 768px) {
  .layout {
    flex-direction: column;
  }
  .sidebar,
  .main {
    width: 100%;
  }
}

グリッドのgap計算(均等分割)

CSS Gridを使わずにflexで均等3カラムを作る際、gapの分だけ幅を引く必要があります。

.card-grid {
  display: flex;
  flex-wrap: wrap;
  gap: 24px;
}

.card {
  /*
    3列: 100% / 3 = 33.333...%
    gapは列間に2つ(3列なら2gap分) → 2 * 24px / 3列 = 16px
  */
  width: calc(100% / 3 - 24px * 2 / 3);
  /* または等価な計算: calc((100% - 24px * 2) / 3) */
}

@media (max-width: 640px) {
  .card {
    width: 100%;
  }
}

CSS Gridのgapプロパティとgrid-template-columnsを使う場合は自動でgapを考慮してくれますが、Flexboxではcalc()による手動計算が必要です。

スクロール対象コンテナの高さ設定(100vh – ヘッダー)

モーダルやサイドパネル、チャットUI等でスクロール可能なコンテナの高さを設定する典型パターンです。

:root {
  --header-h: 60px;
  --footer-h: 80px;
}

.scrollable-area {
  height: calc(100vh - var(--header-h) - var(--footer-h));
  overflow-y: auto;
  -webkit-overflow-scrolling: touch; /* iOS対応 */
}

/* チャットUI: 入力欄が下固定の場合 */
.chat-container {
  display: flex;
  flex-direction: column;
  height: calc(100vh - var(--header-h));
}

.chat-messages {
  flex: 1;
  overflow-y: auto;
}

.chat-input {
  height: 64px;
  flex-shrink: 0;
}

余白の引き算(ネガティブスペース管理)

コンテナにパディングがある中で、内包要素を左右端まで伸ばしたい(いわゆる「はみ出し」)ケースに使います。

.container {
  padding: 0 24px;
  max-width: 960px;
  margin: 0 auto;
}

/* コンテナのパディングを打ち消して全幅に伸ばす */
.full-bleed {
  width: calc(100% + 48px); /* 左右24px×2 = 48px 追加 */
  margin-left: -24px;
  margin-right: -24px;
}

位置指定での活用(top/left/transform代替)

要素を中央配置する際のtransformを使わないアプローチにもcalc()が使えます。

.modal {
  position: fixed;
  width: 480px;

  /* 画面中央に配置: 50% - 要素幅の半分 */
  left: calc(50% - 240px);
  top: calc(50% - 200px);
}

/* 右端から固定オフセットで配置 */
.fab {
  position: fixed;
  bottom: calc(24px + env(safe-area-inset-bottom)); /* iPhone対応 */
  right: 24px;
}

CSS変数(var)との組み合わせ

カスタムプロパティと組み合わせると何がよいか

CSS変数(カスタムプロパティ)とcalc()を組み合わせると、デザイントークンベースの計算が実現できます。基準値を変数に持たせておけば、その変数を変更するだけで関連するすべての計算結果が連動して変わります。

:root {
  --base-space: 8px;    /* スペーシングの基準 */
  --header-height: 60px;
  --sidebar-width: 260px;
  --content-padding: 24px;
}

/* 変数を計算に使う */
.section {
  padding: calc(var(--base-space) * 4) calc(var(--base-space) * 3);
  /* = padding: 32px 24px; */
}

.page-body {
  height: calc(100vh - var(--header-height));
  padding: 0 var(--content-padding);
}

.main-area {
  width: calc(100% - var(--sidebar-width) - var(--content-padding) * 2);
}

レスポンシブブレークポイントを変数で切り替える

メディアクエリと組み合わせて変数の値だけを変えることで、calc()の式はそのまま使い回せます。

:root {
  --header-height: 60px;
  --sidebar-width: 260px;
}

@media (max-width: 768px) {
  :root {
    --header-height: 48px;
    --sidebar-width: 0px; /* スマホではサイドバー非表示 */
  }
}

.content {
  /* 計算式はそのままで、変数の値だけ切り替わる */
  height: calc(100vh - var(--header-height));
  width: calc(100% - var(--sidebar-width));
}

JavaScript連携による動的な変数更新

JavaScriptからCSS変数を更新することで、スクロール位置やユーザー操作に応じてcalc()の計算結果をリアルタイムに変えられます。

:root {
  --scroll-y: 0;
}

.parallax-element {
  transform: translateY(calc(var(--scroll-y) * 0.3px));
}
<script>
window.addEventListener('scroll', () => {
  document.documentElement.style.setProperty('--scroll-y', window.scrollY);
});
</script>

clamp()・min()・max()との使い分け

それぞれの役割

calc()と同じくCSS計算関数ファミリーに属するclamp()・min()・max()は、calc()だけでは表現しづらい「範囲制限」を実現します。2026年現在、これら4つの関数を使い分けることがモダンCSSの基本スキルになっています。

  • calc(): 単一の計算結果を得る。四則演算で1つの値を求めるとき。
  • min(): 複数の値のうち最小値を選ぶ。「最大でもこの値を超えない」上限設定に使う。
  • max(): 複数の値のうち最大値を選ぶ。「最低でもこの値を下回らない」下限設定に使う。
  • clamp(): 最小値・推奨値・最大値の3引数で範囲を固定。流体タイポグラフィやレスポンシブサイズ設定に最適。

min()とmax()の使い方

/* min(): 画面幅とpxのうち小さい方を採用 → 最大幅の制限 */
.container {
  width: min(100%, 1200px);
  /* width: 100%; max-width: 1200px; と同等 */
}

/* max(): 値のうち大きい方を採用 → 最小サイズの保証 */
.touch-target {
  /* タッチターゲットは最低44px確保 */
  height: max(44px, 2.75rem);
}

/* calc()を内部で使う組み合わせ */
.fluid-width {
  width: min(calc(100% - 48px), 960px);
}

clamp()で流体タイポグラフィを実現

clamp()は「最小値, 推奨値, 最大値」の形式で書きます。推奨値には可変単位(vwなど)を使うことで、画面幅に連動しながら上下限を持つ値を1行で表現できます。

.fluid-heading {
  /*
    最小: 1.5rem(24px)
    推奨: 2vw + 1rem(画面幅に連動)
    最大: 3rem(48px)
  */
  font-size: clamp(1.5rem, 2vw + 1rem, 3rem);
}

.fluid-padding {
  padding: clamp(16px, 4vw, 64px);
}

/* calc() + clamp() の組み合わせ */
.section {
  /* コンテナ幅から左右パディングを引いた値を、clampで上下限付きで使う */
  width: clamp(320px, calc(100% - 48px), 960px);
}

calc()とclamp()の選び方

判断基準は「範囲制限が必要かどうか」です。単に計算結果が欲しいだけならcalc()、「この値より小さくも大きくもしたくない」という制約があるならclamp()・min()・max()を選んでください。clamp()の推奨値引数にcalc()の式を書くことも可能で、両者を組み合わせると表現力が格段に上がります。

calc()のネスト(入れ子)

ネストの書き方

CSS Values Level 4仕様でcalc()のネストが正式に許可されています。calc()の中にcalc()を書くことができますが、内側のcalc()は省略して括弧だけにすることも可能です。

/* 内側にcalc()を書く形 */
width: calc(calc(100% - 240px) / 2);

/* 内側のcalc()は省略できる(括弧だけでOK) */
width: calc((100% - 240px) / 2);

/* 変数との組み合わせでネストが深くなる場合 */
.complex {
  margin: calc(var(--base-space) * 2 + (100vw - 1200px) / 2);
}

min()・max()・clamp()の内側でcalc()を使う

min()・max()・clamp()の引数の中でcalc()の式を使う場合、内側のcalc()は省略できます。これはCSS仕様で「数学関数の引数内では計算コンテキストが継続する」ため、括弧だけで計算式を分離できるからです。

/* clamp()内のcalc()は省略可能 */
font-size: clamp(1rem, 1rem + 2vw, 2rem);
/* これは以下と同等 */
font-size: clamp(1rem, calc(1rem + 2vw), 2rem);

/* min()内でcalc()式を使う */
width: min(100% - 32px, 1200px);
/* これは以下と同等 */
width: min(calc(100% - 32px), 1200px);

よくあるエラーと対処法

エラー1: 演算子前後のスペース不足

前述の通り、+と-の前後にスペースが必要です。プロパティが効いていない場合はまずここを疑ってください。ブラウザのDevToolsでCSSプロパティが取り消し線付きで表示されていたら構文エラーのサインです。

/* NG */
width: calc(100%-240px);

/* OK */
width: calc(100% - 240px);

エラー2: ゼロに単位をつけてしまう

calc()の中でも通常のCSSと同様、0には単位をつけなくてよいですが、0pxと書いても動作します。ただし除算の右辺にゼロを置くとゼロ除算になり無効です。

/* OK: 0に単位なし */
margin: calc(0 + 16px);

/* NG: ゼロ除算 */
width: calc(100% / 0); /* 無効 */

エラー3: 型が合わない計算

長さ(px・%・vh等)と数値(単位なし)を加減算しようとするとエラーになります。

/* NG: 長さと数値の加算 */
width: calc(100% + 2);   /* 無効: 2は数値で長さではない */
opacity: calc(0.5 + 10%); /* 無効: opacityは数値だが10%は長さ型 */

/* OK: 同じ型同士 */
width: calc(100% + 2px);
opacity: calc(0.5 + 0.1);

エラー4: カスタムプロパティの値に単位が含まれていない

CSS変数に数値だけを入れてcalc()内で単位を後付けするテクニックは仕様上グレーゾーンでしたが、現在は「数値を変数に入れてcalc()で単位をつける」書き方が多くのブラウザで動作します。ただし確実性を求めるなら単位ごと変数に入れる方が安全です。

:root {
  --size: 240;      /* 単位なし数値 */
  --size-px: 240px; /* 単位付き(推奨) */
}

/* 単位なし変数 + calc()で単位付加(動作するが非推奨) */
width: calc(var(--size) * 1px); /* 動く場合もあるが避けたほうが安全 */

/* 単位付き変数を直接使う(推奨) */
width: var(--size-px);

エラー5: Sass/SCSSの中でcalc()を使うときの#{}の問題

SassでCSS変数とcalc()を組み合わせる場合、Sassが計算を先に評価しようとしてエラーになることがあります。Sass変数をcalc()内で使う場合は#{$variable}で補間するか、Sassの計算とCSS calc()を区別して書く必要があります。

/* Sass内の例 */
/* NG: Sassが計算しようとしてエラー */
/* width: calc($sidebar-width - 20px); */

/* OK: Sass補間を使う */
/* width: calc(#{$sidebar-width} - 20px); */

/* 純粋なCSSカスタムプロパティなら問題なし */
/* width: calc(var(--sidebar-width) - 20px); */

DevToolsでのデバッグ方法

計算結果の確認

ChromeやEdgeのDevToolsでは、calc()の式がどの値に計算されているかをComputedパネルで確認できます。Stylesパネルではcalc()の式そのままが表示され、Computedパネルでは計算後の実際のpx値が表示されます。レイアウトが崩れた場合はComputedパネルで期待値と実際値を比較するのが最短の診断方法です。

  • Stylesパネルでプロパティを確認: calc()の式が正しく構文解析されているかチェック(取り消し線なしがOK)
  • Computedパネルで計算結果を確認: 実際に適用されているpx値を見る
  • Layoutパネルでボックスモデルを確認: widthやpaddingが期待通りのサイズになっているか視覚的に確認

よくある質問(FAQ)

Q. calc()はどのプロパティでも使えますか?

数値・長さ・パーセンテージ・角度・時間などを値として受け取るプロパティであればcalc()を使えます。width・height・margin・padding・top・left・bottom・right・font-size・line-height・transform(の引数)・grid-template-columns・animation-durationなど広範囲で利用可能です。一方でdisplayやpositionなどキーワード値のみのプロパティには使えません。

Q. calc()はパフォーマンスに悪影響がありますか?

通常の使い方では問題ありません。ブラウザはcalc()をスタイルの解決フェーズで評価し、その後はキャッシュされた計算値を使います。アニメーションのtransformプロパティ内でcalc()を使う場合も、GPU合成レイヤーで処理されるため実質的なオーバーヘッドはほぼゼロです。ただし、JavaScriptからCSS変数を頻繁に更新するパターン(スクロールごとなど)では再計算コストが生じるため、will-changeやrequestAnimationFrameと組み合わせて最適化することを推奨します。

Q. clamp()とcalc()はどちらを優先すべきですか?

目的によって使い分けます。「AとBを計算して1つの値を出す」ならcalc()、「計算結果を一定範囲内に収めたい」ならclamp()・min()・max()です。フォントサイズやコンテナ幅のレスポンシブ対応にはclamp()が直感的で便利です。ただしclamp()の推奨値引数にcalc()の式を書くケースは多く、「clamp()にcalc()を入れる」組み合わせが実務では最もよく登場します。

Q. CSS変数(カスタムプロパティ)なしでcalc()を使うべきでしょうか?

小規模なスタイルシートや1箇所だけの計算であれば直書きでも問題ありません。ただし複数箇所で同じ基準値(ヘッダー高・サイドバー幅・スペーシング基準など)を使うなら、CSS変数に切り出してcalc()内でvar()を使う構成を強く推奨します。値が変わったときに1箇所の変更だけで済み、保守性が大幅に上がります。特に:rootに変数を集約し、メディアクエリで変数値だけを更新するパターンはレスポンシブ設計のベストプラクティスです。

Q. サポートしていない古いブラウザへの対応はどうすればよいですか?

IE11のサポートは2022年6月に終了しており、2026年時点では実質的に考慮不要です。ただしあえてフォールバックを用意する場合は、calc()の前に固定値を書くカスケードを使います。

.element {
  /* フォールバック: 古いブラウザはこちらを使う */
  width: 75%;
  /* モダンブラウザはcalc()で上書き */
  width: calc(100% - 260px);
}

まとめ

CSS calc()はレスポンシブWebデザインの根幹を支える計算関数です。「異なる単位を混在させた計算」「ブラウザに計算を任せて常に正確なレイアウト」というこの2点が、calc()を使う最大の理由です。基本をおさえたうえで、CSS変数やclamp()・min()・max()と組み合わせることで、メンテナンス性の高いモダンなCSSが書けるようになります。

  • +と-の前後にスペースが必須——これを忘れるとプロパティ全体が無効になる
  • 異なる単位(%+px、vh+remなど)を1つの式に書ける——calc()最大の強み
  • CSS変数(var)と組み合わせてデザイントークン管理——変数の値を変えるだけで全体が連動する
  • clamp()はcalc()と別物——範囲制限が必要なときはclamp()/min()/max()を使う
  • 100vh – ヘッダー高・100% / 3 – gap・full-bleed計算が代表的な実践パターン
  • DevToolsのComputedパネルで計算結果を確認できる

関連記事

WithCodeを体験できる初級コース公開中!

WithCodeを体験できる初級コース公開中!

初級コース(¥49,800)が完全無料に!

  • 期間:1週間
  • 学習内容:
    ロードマップ/基礎知識/環境構築/HTML/CSS/LP・ポートフォリオ作成
    正しい学習方法で「確かな成長」を実感できるカリキュラム。

副業・フリーランスが主流になっている今こそ、自らのスキルで稼げる人材を目指してみませんか?

未経験でも心配することはありません。初級コースを受講される方の大多数はプログラミング未経験です。まずは無料カウンセリングで、悩みや不安をお聞かせください!

この記事を書いた人

WithCodeでWeb制作を習得後、フリーランスエンジニアとして活動。HTML/CSS・JavaScript・WordPress案件を中心に年間20件以上の制作実績を持つ。「難しい技術をわかりやすく」をモットーに、初心者〜中級者向けの技術記事を執筆。副業・フリーランス独立を目指す方に向けた情報発信に注力している。

– service –WithGroupの運営サービス

  • WithCode
    - ウィズコード -

    スクール

    「未経験」から
    現場で通用する
    スキルを身に付けよう!

    詳細はこちら
  • WithFree
    - ウィズフリ -

    実案件サポート

    制作会社のサポート下で
    実務経験を積んでいこう!

    詳細はこちら

公式サイト より
今すぐ
無料カウンセリング
予約!

目次