CSSでレイアウトを組んでいると、「幅を50%にしたのに、余白を足したら右にはみ出した」「サイドバーは固定幅で、残りはメインにきっちり使わせたい」——こんな“あと数ピクセル”のズレでつまずいた経験はありませんか。
割合(%)だけ、あるいは固定値(px)だけでは、このズレはなかなか埋められません。そこで出番になるのがcalc()です。calc()は、%とpxのように単位の違う値どうしを足し引きして、サイズをその場で計算させられるCSSの関数です。
私はWeb制作を長年やってきましたが、レスポンシブが当たり前になってから calc() を書く頻度は一気に増えました。「画面の高さからヘッダー分だけ引きたい」「余白込みで3等分したい」といった、実案件でしか出てこない要望に素直に応えてくれるからです。
とはいえ、便利だからと数式を盛りすぎると、後から見て意味の取れないコードになりがちです。この記事では、四則演算や単位混在といった基本ルールから、%との違い、可変レイアウトや100vhの落とし穴まで、コピペで動く例つきで整理します。読み終えるころには、「なんとなく」だった calc() を自信を持って使い分けられるようになっているはずです。
calc()とは何か|CSSで“計算”ができる関数
calc()は、CSSの値の中で四則演算(+・−・×・÷)ができる関数です。単なる数値ではなく、式そのものを値として書けるのが特徴です。
いちばんの強みは、%とpxのように性質の違う単位を1つの式に混ぜられること。たとえば「親要素の幅いっぱい(100%)から、固定サイズの余白だけを引く」という指定が、そのまま1行で書けます。
.box {
width: calc(100% - 300px);
}
ブラウザが表示のたびに計算してくれるので、ウィンドウ幅が変わっても常に「300pxを引いた残り」を保ってくれます。calc()はモダンブラウザすべてで安定して使えます(Baselineで“広く利用可能”=2015年時点で主要ブラウザ対応済み)。安心して実務投入できる機能です。
書き方の基本ルール|演算子の前後スペースに注意
calc()でいちばん多いつまずきが、演算子まわりの書き方です。ここだけは正確に押さえておきましょう。
足し算「+」と引き算「−」は、演算子の前後に必ず半角スペースが要ります。スペースを詰めると計算が無効になり、指定そのものが効きません。掛け算「*」と割り算「/」はスペースがなくても動きますが、読みやすさのために空けておくのが無難です。
/* OK:前後にスペースあり */
width: calc(100% - 20px);
/* NG:スペースなしで無効になる */
width: calc(100%-20px);
もう一つ、掛け算と割り算には単位のルールがあります。掛け算は片方だけが単位付きでなければいけません(20px * 3はOK、20px * 3pxはNG)。割り算は原則、単位のない数で割ります(calc(100% / 3))。
入れ子とvar()との合わせ技
calc()は入れ子にできます。中のcalc()は単なるカッコとして扱われるので、計算の順番を明示したいときに便利です。CSS変数(カスタムプロパティ)と組み合わせると、さらに読みやすくなります。
:root {
--gap: 20px;
--cols: 3;
}
.card {
/* 全体から余白を引いて3等分 */
width: calc((100% - var(--gap) * (var(--cols) - 1)) / var(--cols));
}
数値をハードコードせず変数で持たせておけば、列数や余白を1か所直すだけで全体に反映できます。保守性がぐっと上がるので、繰り返し使う値は変数化がおすすめです。
%指定との違い|なぜcalc()が必要になるのか
%は親要素に対する割合を返すだけのシンプルな指定です。手軽ですが、「割合」しか表現できません。
これに対してcalc()は、割合に固定値や別単位を組み合わせられるのが決定的な違いです。「50%ぴったり」ではなく「50%から余白の10pxを引いた幅」のような、現実のデザインで本当に必要になる指定ができます。
| 項目 | % | calc() |
|---|---|---|
| 扱える値 | 割合のみ | %・px・remなど混在OK |
| 計算 | できない | 四則演算できる |
| 向いている用途 | 単純な分割 | 余白込みの調整・補正 |
ざっくり言えば、%は「理想的な分割」、calc()は「現実的な微調整」の道具です。両者は競合するものではなく、役割が違うと考えると使い分けがはっきりします。
実務で使うcalc()パターン|よくあるレイアウト例
ここからは、私が実際の案件でよく書く定番パターンを紹介します。どれもコピペしてそのまま試せます。
サイドバー固定+メイン可変
サイドバーを固定幅にして、残り全部をメインに使わせたい——calc()がいちばん活きる場面です。
.sidebar {
width: 300px;
}
.main {
width: calc(100% - 300px);
}
サイドバーの300pxを引いた残りがメインに割り当てられるので、画面幅が変わってもレイアウトが崩れません。
余白込みで均等に並べるカード
3枚のカードを、間の余白(gap)を含めてきれいに3等分したいときの書き方です。
.card {
width: calc((100% - 40px) / 3);
}
「全体から余白の合計40pxを引き、残りを3で割る」というだけの式です。式が長く見えても、意味はいたってシンプルです。
ファーストビューの高さ調整
画面の高さいっぱいから、固定ヘッダーの高さだけを引きたいケース。
.hero {
height: calc(100vh - 80px);
}
ヘッダーが80pxなら、その下にちょうど画面いっぱいの領域を作れます。ファーストビューの作り込みで重宝します。ただし100vhにはスマホ特有の落とし穴があるので、次で補足します。
100vh問題への対処
スマホでは100vhがアドレスバーの領域まで含んでしまい、実際の表示より高くなることがあります。その結果、画面下がわずかに隠れたり、スクロールで余分な隙間が出たりします。
現在は、表示領域に追従するdvh(Dynamic Viewport Height)などの新単位が使えます。calc()と組み合わせれば、より安定した高さ指定になります。
.hero {
height: calc(100dvh - 80px);
}
calc()そのものが100vh問題を直すわけではありませんが、単位をdvhに替えるだけで多くの端末で違和感が減ります。
clamp()・min()・max()との関係|calc()の“親戚”たち
calc()を覚えると、セットで理解しておきたいのがmin()・max()・clamp()です。これらもCSSで値を計算する関数で、中身にcalc()と同じ式(四則演算や単位混在)を書けます。
役割はそれぞれ、min()は「小さいほうを採用」、max()は「大きいほうを採用」、clamp()は「最小・推奨・最大の3つを指定して範囲に収める」です。「上限・下限を決めたい」ときはcalc()を無理に組むより、これらのほうが素直に書けます。
/* 最小16px、基本は幅に応じて可変、最大24pxに収める */
font-size: clamp(16px, 4vw, 24px);
/* 100%とはいえ最大は600pxまで */
width: min(100%, 600px);
calc()が「足し引きして1つの値を作る」道具なら、clamp()たちは「値の範囲を制限する」道具です。組み合わせて使うこともできます。
関連記事:CSSでフォントサイズの最大値・最小値を指定する方法|clamp(), min(), max()完全解説
Flex・Gridとの使い分け|まず“シンプルな方”を選ぶ
今のCSSでは、FlexboxやGridの進化で、以前ならcalc()が必要だった余白調整の多くが不要になりました。とくにgapプロパティのおかげで、カードの間隔をcalc()で計算する場面はかなり減っています。
.grid {
display: grid;
grid-template-columns: repeat(3, 1fr);
gap: 20px;
}
これだけで、余白込みの3等分がcalc()なしで実現できます。大事なのは「calc()を使うか」ではなく、「どれがいちばんシンプルで読みやすいか」で選ぶことです。
それでもcalc()が要る場面は残ります。GridやFlexで大枠を組みつつ、一部の要素だけ「固定値を引いた幅」にしたいときなど、両者は補い合う関係です。
関連記事:グリッドデザインとは?初心者にもわかるWeb制作の整列と余白の基本&CSS Grid入門
使うべき場面と、使わない判断
calc()は万能ではありません。使いどころを見極めると、コードがぐっと読みやすくなります。
calc()が向いている場面
- 固定値と可変値を組み合わせたいとき(100% − 300px など)
- 余白を差し引いた幅を作りたいとき
- 残りのスペースをきっちり使わせたいとき
使わなくていい場面
- 単純な割合だけで足りるとき(素直に%で書く)
- FlexやGridの
gap・frで解決できるとき - 上限・下限を決めたいとき(clamp()などのほうが明快)
迷ったら、式を日本語に置き換えてみるのがコツです。「全体から余白を引いて、残りを3で割る」——こう説明できるなら、その式は健全です。逆にうまく言葉にできない式は、たいてい複雑すぎるサインです。
「CSS calc()の使い方」まとめ
calc()は、CSSの「あと数ピクセルが合わない」を解決してくれる、地味だけど頼れる機能です。
単純な割合指定では埋められない現実のズレを、%とpxをまたいだ計算できれいに吸収してくれます。とくに、固定幅と可変幅が混在するレイアウトや、余白を含めた正確な幅・高さの設計では、calc()の効果をはっきり実感できるはずです。
書き方で最初に覚えるべきは、「+と−の前後には半角スペースが必須」という一点だけ。ここさえ外さなければ、あとは四則演算のイメージそのままで扱えます。CSS変数と組み合わせれば、列数や余白を1か所直すだけで全体を調整でき、保守もぐっと楽になります。
一方で、FlexboxやGridのgap、上限下限を決めるclamp()など、calc()より素直に書ける手段も増えました。無理にcalc()に寄せる必要はありません。判断基準はいつも「最もシンプルで読みやすい方法はどれか」です。必要な場面で迷わず出せて、不要な場面では潔く使わない。この線引きができれば十分です。
考え方はとてもシンプルで、「全体から何かを引く」「残りを分ける」——本質はこれだけです。式を丸暗記する必要はありません。意味で捉えられれば、自然と手が動くようになります。まずは今回のサイドバー固定やカード3等分の例をコピペして、自分の案件で一度動かしてみてください。一度つかめば、レイアウトの自由度が一段広がるのを実感できるはずです。