CSSでレイアウトを組む際、多くの開発者が一度は悩むのが「余白」の扱いです。
marginとpaddingはどちらを使うべきか?margin-topとmargin-bottomはどちらで統一すべきか?- ショートハンドは使うべきか、個別プロパティを使うべきか?
これらのルールが曖昧なまま開発を進めると、スタイルの上書きが発生したり、修正に手間取ったりと、保守性の低いCSSが出来上がってしまいます。
この記事では、一貫性があり、将来の変更にも強い「余白設計」のためのルールを解説します。
margin と padding の使い分け
CSSのボックスモデルにおいて、余白は margin(外側)と padding(内側)に明確に分けられます。この区別を意識することが、レイアウト設計の第一歩です。
基本ルール: 要素の内側は padding、外側は margin
padding( 内側 )- 要素のボーダー(
border)の内側に適用される余白です。 - 要素自身の「内側」を広げたい時に使います。
background-colorやborderの範囲に影響します。
- 要素のボーダー(
margin(外側)- 要素のボーダーの外側に適用される余白です。
- 他の要素との「距離」を取りたい時に使います。
background-colorやborderの範囲に影響しません。
例えばどんな時?
paddingを使うケース- ボタンのテキストと枠線(ボーダー)の間の余白
- カード型コンポーネントの枠線と内部コンテンツ(画像やテキスト)の間の余白
- 背景色(
background-color)が設定されたボックスで、背景色の範囲を広げたい時
marginを使うケース- 見出し(
h2)と本文(p)の間の距離 - 横並びにしたカードとカードの間の隙間
- ヘッダーコンポーネントとメインコンテンツコンポーネントの間の距離
- 見出し(
NGパターン
最もよくある間違いは、要素間の距離を padding で取ろうとすることです。
/* NG例 */
.box1 {
background: skyblue;
/* 弟要素との距離を取るためにpadding-bottomを使う */
padding-bottom: 30px;
}
.box2 {
background: orange;
}
この場合、.box1 の背景色(skyblue)が padding-bottom の分まで不必要に広がってしまい、意図した見た目になりません。要素と要素の距離は、必ず margin で定義しましょう。
top と bottom どちらを使うか (マージンの方向)
margin-top と margin-bottom のどちらを使って要素間の距離を定義するか。これは「どちらが絶対に正しい」というものではありませんが、「どちらか一方に統一する」ことが重要です。
ルールが混在すると、マージンが相殺されたり(Collapsing Margins)、二重で当たったりして、レイアウト崩れや意図しない余白の原因になります。
推奨: margin-top に統一する
このブログでは margin-top で統一することをおすすめします。
理由: 要素追加時の編集がシンプルになるから
Webページは通常、上から下にコンテンツが流れます(Block Direction)。margin-top で統一するとは、「自分より上にある要素との距離を、常に自分が定義する」というルールです。
このルールが、要素の追加・変更時に大きなメリットをもたらします。
margin-top 統一の場合: 後から新しい要素(例: .box3)を .box2 の下に追加したくなったとします。
<div class="box1">...</div>
<div class="box2">...</div>
<div class="box3">...</div>
/* style.css */
.box1 { ... }
.box2 {
margin-top: 20px;
}
.box3 { /* 追加した要素のCSSだけ編集すればOK */
margin-top: 20px;
}
新しく追加した .box3 のCSSファイル(またはスタイルブロック)に margin-top を記述するだけで完結します。
もし margin-bottom 統一だったら?
margin-bottom 統一(自分の下の要素との距離を自分が定義するルール)の場合、.box3 を追加するには、その上にある .box2 のCSSを探し出し、margin-bottom を設定する必要があります。
/* bottom統一だと... */
.box1 {
margin-bottom: 20px;
}
.box2 {
/* .box3を追加するために、このCSSを探して追記する必要がある */
margin-bottom: 20px;
}
.box3 { ... }
コンポーネント指向の開発が主流の現代において、新しく追加したコンポーネント(.box3)のスタイルだけを編集できる方が、はるかに効率的で安全です。
ショートハンドか個別プロパティか
margin: 10px 20px; のようなショートハンドは便利ですが、可読性と安全性の観点から使い分けが必要です。
基本: 可読性の高い「個別プロパティ」がおすすめ
原則として margin-top や padding-left のような個別プロパティを使うことを推奨します。
/* 良い例(個別指定) */
.card {
margin-top: 10px;
margin-bottom: 10px;
padding-left: 15px;
}
メリット (可読性): margin-top: 10px; は「上マージンが10px」と一目でわかります。margin: 10px 0 0 0; よりも直感的です。
メリット (安全性): 意図しない値を上書きする事故を防げます。例えば、margin-top だけを変更したいのにうっかり margin: 10px; と書いてしまい、設定されていた左右のマージンまで上書きしてしまう、というミスがなくなります。
ショートハンドがおすすめのケース
もちろん、ショートハンドが効率的で、可読性を損ねない(むしろ高める)パターンもあります。以下のような場合は積極的に使いましょう。
ゼロにリセット
margin: 0;padding: 0;
中央寄せ
margin: 0 auto;(ブロック要素の中央揃え)
上下、左右に同じ値を設定する場合
margin: 10px 20px;(上下に10px、左右に20px)padding: 8px 16px;(ボタンの余白指定などで多用されます)
すべての方向に別の値を設定するケース
- 特に
paddingで、上下左右の余白を意図的に細かく調整したい場合。 padding: 5px 10px 15px 20px;(上5px, 右10px, 下15px, 左20px)
ショートハンドと個別プロパティの併用ケース
中央寄せと上マージンを設定する。のようなケースはよくあります。その場合はショートハンドと個別プロパティを併用するのがオススメです。
.card {
margin: 0 auto;
margin-top: 10px;
}
ショートハンドにまとめる方が記述量が減って楽という意見もありますが、エディターの補完機能を使うなら別々に指定する方が早くかけるケースが多いと思います。
mauto → margin: 0 auto;
mt10 → margin-top: 10px;
一点、記述順にだけ注意してください。下記の用に記述すると後で記述した方が無効になります。
.card {
margin-top: 10px;
margin: 0 auto;
}
gapとmarginの使い分け
これまでは margin を使って要素間の距離を管理するのが一般的でしたが、Flexbox や Grid の登場により、gap プロパティという、より強力でシンプルな選択肢が生まれました。
display: flex または display: grid を使う場合、アイテム間の余白は margin ではなく gap を使うことを優先で検討してください。
gap とは?
gap は、Flexbox や Grid のコンテナ(親要素)に指定し、アイテム(子要素)とアイテムの間の隙間を定義するプロパティです。
.container {
display: flex;
flex-direction: column;
gap: 20px; /* アイテムとアイテムの間にだけ20pxの隙間ができる */
}
gap を使う最大のメリット
gap の最大のメリットは、「最後の要素」の不要なマージンを気にする必要がなくなることです。
margin の場合 (面倒な点)
margin-top 統一ルール(セクション2)を採用しても、一番上の要素にはマージンが不要なため、以下のような工夫が必要でした。
.item:not(:first-child) {
margin-top: 0;
}
(または margin-bottom 統一の場合、.item:not(:last-child) が必要)
gap の場合 (シンプルな点)
gap はアイテム間にしか適用されません。コンテナの外側(最初の子の上や、最後の子の下)には適用されないため、余計なセレクタが一切不要になります。
.container {
display: flex;
flex-direction: column;
gap: 20px; /* これだけでOK! */
}
.item {
/* marginに関する記述が不要になる */
}
gapは非常に便利ですが、万能ではありません。marginと正しく使い分けるためのルールを整理します。
gap(優先)- 使う場面:
display: flexまたはdisplay: gridで、アイテム間の隙間がすべて均一な場合。 - 役割: アイテムとアイテムの「均一な隙間」。
- 使う場面:
margin- 使う場面:
gapが使えないレイアウト(display: blockなど)の時。- コンポーネント全体(親)と、他の要素との距離を取りたい時。
- (重要)
flexやgridを使っていても、アイテム間の距離がバラバラな場合。
- 役割: 要素の「外側の距離」または「個別に指定する距離」。
- 使う場面:
gapが適さないケース:アイテム間の距離がバラバラな場合
gapプロパティは、全てのアイテム間に同じ値の隙間を設定します。
もし、デザインの要件として「1番目と2番目の間は10px、2番目と3番目の間は30px」のように、アイテム間の距離がそれぞれ異なる場合は、gapは使えません。
このような場合は、gapを使わずに、従来通りアイテム個別にmargin(セクション2のmargin-top統一ルールなど)を使って距離を指定するのが適切です。
/* 距離がバラバラなため、gapではなくmarginを使う */
.container {
display: flex;
flex-direction: column;
/* gap: 20px; ← これは使えない */
}
.item-1 { ... }
.item-2 {
margin-top: 10px; /* 1番目との距離 */
}
.item-3 {
margin-top: 30px; /* 2番目との距離 */
}
まとめ
以下のルールを使い分けると、CSSが非常にクリーンになります。
- アイテム間が均一:
flex/grid+gap - アイテム間が不均一:
flex/grid+margin(個別に指定) - コンポーネントの外側:
margin(セクション2のmargin-top統一ルールを適用)