margin とは
margin は要素の border の 外側 の余白です。常に透明で、ほかの要素を押しのける役割を持ちます。例では、青いボックスの周りの margin から、灰色のコンテナが透けて見えています:
灰色の帯はボックスの一部ではありません。ボックス自身の背景は border で止まります。要素の背景が見える余白が欲しいときは padding を使います。
margin のショートハンド
margin には 1 から 4 つの値を、padding と同じ時計回りの順番で書きます:
| 宣言 | 上 | 右 | 下 | 左 |
|---|---|---|---|---|
margin: 10px; | 10 | 10 | 10 | 10 |
margin: 10px 20px; | 10 | 20 | 10 | 20 |
margin: 10px 20px 30px; | 10 | 20 | 30 | 20 |
margin: 10px 20px 30px 40px; | 10 | 20 | 30 | 40 |
各辺には専用のプロパティ (margin-top、margin-right、margin-bottom、margin-left) と、書字方向に従う論理プロパティ (margin-inline-start、margin-inline-end、margin-block、margin-inline) もあります。
padding と違い、margin には auto とマイナスの値が使えます:
| 値 | 例 | 補足 |
|---|---|---|
| 長さ | 16px, 1.5rem | いちばんよく使う |
| パーセント | 5% | 4 辺すべて、包含ブロックの幅が基準 |
auto | margin: 0 auto | ブラウザが残りの空間で埋める |
| マイナス | margin-top: -10px | 要素や隣の要素を引き寄せ、重なることもある |
margin: 0 auto で中央寄せ
margin: 0 auto は、ブロックを横方向の中央に寄せる定番の方法です。両側の auto は、残りの空間を均等に分けるようブラウザに指示します。コンテナより小さい幅が必要で、そうでないと分ける余りがありません:
通常フローでは auto の margin で縦の中央寄せはできず (縦の auto の margin は 0 になります)、インライン要素には何の効果もありません。中央寄せの全体像は div を中央寄せする方法 を参照してください。
margin の相殺
2 つの縦の margin が接すると、足し算されません。ブラウザは大きいほうだけを残します。ここでは 1 つ目のボックスが margin-bottom: 30px、2 つ目が margin-top: 20px で、間隔は 50px ではなく 30px です:
相殺は意図された仕様です。段落や見出しがそれぞれ自分の余白を持っていても、接する部分で余白が倍にならずに済みます。つまずきやすいのは 2 つ目のケースで、子の上の margin が親の外に はみ出す ときです:
1 つ目の親では、子の 30px の margin が親の上端を突き抜けて相殺され、親の中に灰色の余白を作る代わりに親全体を下に押し下げています。次のどれかで防げます:
- 親に
display: flow-rootを指定する (overflow: hiddenと違い、何も切り取りません)。 - 親の上端に padding か border を付ける。
- 親を flex か grid にする。flex アイテムと grid アイテムの margin は相殺されません。
横の margin は相殺されません。float した要素や絶対配置された要素の margin も相殺されません。
マイナスの margin
マイナスの margin は逆方向に引っ張ります。上側や開始側では要素そのものが動き、下側や終了側では次の要素を引き寄せます。ボックス同士が重なることもあります:
flexbox での margin auto
flex コンテナの中では、auto の margin がその側の空き空間をすべて取ります。行の中の 1 つのアイテムを端まで押しやるいちばん簡単な方法で、flexbox では auto が縦方向にも効きます:
margin-inline-start: auto は「Log in」の前に空き空間を置くので、左から右のページでも右から左のページでも、行の終わりに寄ります。
よくある間違い
- 幅のない要素に
margin: 0 auto。 ブロックはすでにコンテナいっぱいに広がっています。widthかmax-widthを指定しましょう。 - インライン要素に
margin: auto。 インラインのままのspan、a、imgの auto の margin は 0 です。display: blockにしましょう。 - 2 つの縦の margin の合計を期待する。 大きいほうに相殺されます。flex や grid の
gapを使うか、margin の方向を一方にそろえましょう。 - 子の margin が親を押し下げる。 親子間の相殺です。親に
display: flow-rootを追加しましょう。 - 背景を付けたい余白に margin を使う。 margin は透明です。padding を使いましょう。
よくある質問
CSS の margin とは何ですか?
margin は要素の border の外側の余白です。透明で、隣の要素を押しのけます。margin、または片側だけのプロパティ margin-top、margin-right、margin-bottom、margin-left で指定します。
margin: 0 auto は何をしますか?
上下の margin を 0 にし、横方向の残りの空間を左右の margin に均等に分けます。これでブロック要素が横方向の中央に配置されます。要素にはコンテナより小さい幅が必要です。例: max-width: 600px。
margin auto で中央寄せできないのはなぜですか?
多くの場合、要素に幅がない (ブロックはコンテナいっぱいに広がるので分ける余りがない) か、要素がインライン (初期状態の span、a、img) で auto の margin が 0 になるかのどちらかです。幅と display: block を指定するか、親から flexbox や grid で中央に寄せましょう。
margin の相殺とは何ですか?
2 つの縦の margin が接すると (たとえばある段落の下の margin と次の段落の上の margin)、ブラウザは足し算せず、大きいほうだけを使います。これは通常フローにあるブロックボックスの縦の margin だけに起き、flex や grid のレイアウトでは起きません。
margin にマイナスの値は使えますか?
使えます。マイナスの margin は要素をその方向に引き寄せるか、次の要素を上に重ねるので、ボックス同士が重なることがあります。細かい位置合わせや、要素をコンテナの padding の外にはみ出させるのに便利です。