marginプロパティその2 marginの相殺・重なり(実技編2-17)

実技編

上下あるいは左右に隣り合う要素の間隔』である『marginプロパティ』について、その1では基本的な使い方を解説しました。
※『左右に隣り合う要素の間隔』については、現時点では『要素を横に並べる』ことができないので解説しません。

『その2』となる今回は、『marginの相殺』のケースについて解説していきます。

この解説の理解を助ける事前知識
  • marginプロパティ その1
  • デフォルトスタイルシート
  • background-colorプロパティ
  • borderプロパティ
  • div要素による要素のグループ化

『上下に向かい合うmargin』の相殺

上下に隣り合う要素があり

<h1>上の要素</h1>
<p>下の要素</p>

上の要素には『下方向へのmargin(margin-bottom)』
下の要素には『上方向へのmargin(margin-top)』
をそれぞれ設定すると

h1{
     width:500px;
     background-color:#ff7799;
     margin-bottom:100px;          下向きのmargin『100px』
}
p{
     width:500px;
     background-color:#66ccff;
     margin-top:40px;              上向きのmargin『40px』
}

それら2つのmarginは
上下に向かい合っている』と捉えることができます。

その時、それら2つのmarginは、下図のような関係で配置されます。

上下に向かい合うmarginは互いに重なり合いぶつかり合うことはありません
重なる部分は『相殺』され、比較して大きい数値のmarginが採用されます。

上記コードでは
2つの向かい合うmarginのうち、数値の大きい『100px』がこの要素間の間隔として挿入されます。

上下に向かい合うmarginは相殺され、数値の大きい方が採用される

親子要素にそれぞれ設定されたmarginの相殺

marginが相殺されるケースは他にもあります。
親子の関係にある要素それぞれ』にmarginが指定された場合です。
状況によって『相殺されるケース』『相殺されないケース』両方ありますので、順番に解説します。

親子要素間でmarginが相殺されるケース

まずは以下のHTMLを用意します。

<h1>h1の内容</h1>
<div>
    <p>pの内容</p>
</div>

この構造に以下のようなスタイルを与えてみます。

h1{
     width:500px;
     background-color:#ff7799;
}
p{
     width:300px;
     background-color:#66ccff;
     margin-top:0;margin-bottom:0;※
}
div{
     background-color:orange;
     margin-top:30px;
}

デフォルトスタイルシートの働きによってp要素に挿入される上下のmarginは、『0(ゼロ)』と記述することで無効化しています。

h1とpの間隔が挿入されているように見えますが、これはh1の兄弟であるdivの『margin-top』です。pにはmarginは挿入されていません。

これで、『divとp、という親子要素』のうち、まずは親要素であるdivに『margin-top』が設定できました。

続けて子要素であるpにも親要素divと同じ方向にmarginを設定します。
親要素divに設定したよりも『大きな数値』で指定してみましょう。
違いが明確に判るように思い切り大きくしてみます。

h1{
     width:500px;
     background-color:#ff7799;
}
p{
     width:300px;
     background-color:#66ccff;
     margin-top:200px;
     margin-bottom:0;
}
div{
     background-color:orange;
     margin-top:30px;
}

図を見て驚かれた方もいらっしゃるのではないでしょうか。

子要素pのmarginが親要素divの外に『とび出て』います。『親という囲いを突き抜けた』と言ってもいいかもしれません。
これはルールで定められた仕様なのです(例外ケースあり)。

子要素のmarginは親要素から外に出る
※例外ケース(後述)あり

このように、子要素のmarginが親要素を突き抜けて外に出た場合、同じ方向に設定された親子それぞれのmarginのうち『数値の小さい(短い)方』は意味を成していないことが解ります。

これが親子の要素に起こるmarginの相殺です。

親子要素間でmarginが相殺されないケース

親子要素間のmarginが相殺されないケースは、先ほどの『相殺されるケース』のコードにひとつ手を加えるだけで再現できます。

同じ画像をもう一度見ておきます。

親要素div、その子要素p、それぞれに設定したmargin-topのうち、数値の小さい(短い)方であるdivの『margin-top:30px』は、挿入されてはいるものの、この状況では意味を成していません。
相殺されている状態です。

この『親要素div』に『borderプロパティ』を設定してみると、あることが起こります。

先ほどのCSSに下記のように追記してみましょう。(赤字部分
borderの値(太さや線種、色)はなんでも構いません。

h1{
     width:500px;
     background-color:#ff7799;
}
p{
     width:300px;
     background-color:#66ccff;
     margin-top:200px;
     margin-bottom:0;
}
div{
     background-color:orange;
     margin-top:30px;
     border:10px solid green;
}

はっきりと変化しましたね。

結論から言いますと、親要素divにborderを設定したことで、子要素pのmargin-topが親要素divの内側に『閉じ込められ』ました。
このように親要素の『border』は、子要素のmarginを閉じ込める働きがあります。

閉じ込められた子要素pの『margin-top:200px』は親要素divを突き抜けることなく、内側に挿入されます。

そして親要素divに指定された『margin-top:30px』は、自身のborderの外側に従来どうり挿入され、上下に隣り合うh1との間隔となります。

親要素とその子要素それぞれのmarginが相殺されることなく、別々の間隔を形成するというケースですね。

なお、『border』の他に『padding』も子要素のmarginを内側に閉じ込める働きを持っています。

前述のコードの『border』の行を削除して、『padding』に書き換えましょう。
もちろん『border』と『padding』を併用してもいいのですが、検証を優先するためここでは『padding』のみにしておきます。

h1{
     width:500px;
     background-color:#ff7799;
}
p{
     width:300px;
     background-color:#66ccff;
     margin-top:200px;
     margin-bottom:0;
}
div{
     background-color:orange;
     margin-top:30px;
     padding-top:40px;   ←borderを削除しpadding-topを追加
}

『border』と同様に親要素divの『padding-top』が子要素pの『margin-top:200px』を内側に閉じ込めています。

親要素に設定された『border』や『padding』は、子要素のmarginを内側に閉じ込める

まとめ
  • 上下に向かい合うmarginには相殺が発生し、比較して数値の大きい方が挿入される
  • 親子の関係にある要素間では、子要素のmarginは親要素を突き抜けて外に出る
    ただし、親要素に『border』や『padding』が設定されている場合、子要素のmarginを内側に閉じ込める

今回はmarginの相殺について解説しました。
marginはページのレイアウトにおいて欠かすことのできない重要な項目です。
反復や様々な状況を通してmarginに対する理解を深めておいてください。

最後までお読みくださりありがとうございました。

おつかれさまでした。

タイトルとURLをコピーしました