CSSで子要素の上マージンが親の外へはみ出すのを防ぐには
親要素の中の子に付けた margin-top が親の外へ突き抜けるのを、display: flow-root で防ぐ基本形を示す。
隣り合う要素のマージンが重なって一つになる相殺の仕組みと、止め方もあわせて確認できる。
公開:
<div class="wrap"><div class="parent"><p class="child">子の margin-top: 24px</p></div></div>.wrap {
width: 260px;
border: 1px dashed #94a3b8;
font: 14px system-ui;
}
.parent {
display: flow-root;
background: #dbeafe;
}
.child {
margin: 24px 0 0;
line-height: 1.7;
}親に display: flow-root を付けると、親が独立したレイアウトの塊になり、子の margin-top が親の内側に収まる。
親と子のマージンが重なって親の外へ出る「マージン相殺」を、見た目に副作用を出さずに止めるためである(親の中に並ぶ兄弟どうしの相殺はそのまま残る)。
子の上マージンが親の外へ突き抜ける
ブロック要素の親と最初の子のあいだに border・padding・行ボックスのような仕切りがないと、子の margin-top は親の外側に出てしまう。
親の背景は子のマージンぶん下がらず、子の文字が親の上端に張り付いて見える。
.wrap {
width: 260px;
border: 1px dashed #94a3b8;
font: 14px system-ui;
}
.parent {
background: #dbeafe;
}
.child {
margin: 24px 0 0;
line-height: 1.7;
}.wrap {
width: 260px;
border: 1px dashed #94a3b8;
font: 14px system-ui;
}
.parent {
display: flow-root;
background: #dbeafe;
}
.child {
margin: 24px 0 0;
line-height: 1.7;
}隣り合う要素の余白は足し算にならない
縦に並んだブロック要素の margin は、大きい方に重なって一つになる。
上下に 20px ずつ付けた 2 つの箱の間隔は、40px ではなく 20px である。
間隔を足し算にしたいときは、並べる側を display: flex と flex-direction: column にする。
flex や grid の子どうしのマージンは相殺されない。
.stack {
width: 200px;
border: 1px dashed #94a3b8;
font: 14px system-ui;
}
.box {
margin: 20px 0;
padding: 8px 12px;
background: #dbeafe;
}.stack {
display: flex;
flex-direction: column;
width: 200px;
border: 1px dashed #94a3b8;
font: 14px system-ui;
}
.box {
margin: 20px 0;
padding: 8px 12px;
background: #dbeafe;
}どの方法で止めるか
親と子の相殺を止める方法は複数あり、副作用が違う。
display: flow-root: 子のマージンが親の外へ突き抜けるのを止めるだけで、見た目は変わらない- 親に
paddingまたはborderを付ける: 見た目に余白や線が増える overflow: hidden: 突き抜けは止まるが、はみ出す影や絶対配置の子が切れる- 親を
display: flexやdisplay: gridにする: 子のマージンは相殺されないが、子の並び方も変わる
まず display: flow-root を試し、レイアウトを変えたいときだけほかの方法を選ぶ。