マージンの相殺

 ■ 微妙なずれ

作成したwebページで、左右に並べた画像やテキストが微妙にずれます(フロートを使ったとき)。 これまでは、画面をみながら margin-top や margin-bottom で調整(その場しのぎ)をしてきました。 CSSによる段組(マルチカラム)レイアウト講座 を拝見したときに「マージンの相殺」という言葉を見かけて、少し調べてみることにしました。

参考資料
Cascading Style Sheets level 2 (CSS2) Specification[W3C 勧告 1998年5月12日]
http://www.swlab.it.okayama-u.ac.jp/man/rec-css2/box.html
http://www.swlab.it.okayama-u.ac.jp/man/rec-css2/box.html

Cascading Style Sheets Level 2 Revision 1 (CSS 2.1) Specification[W3C 勧告候補 2007年7月19日]
http://www.w3.org/TR/CSS21/box#collapsing-margins
http://hp.vector.co.jp/authors/VA022006/css/box.html#collapsing-margins
 ■ ボックスモデル

ボックスエリア

もっとも内側にあるのが内容領域(Content)、 以下外側に向かって順にパディング(Padding)、ボーダー(Border)、マージン(Margin)領域と続きます。 マージンは最も外側の領域であり、この領域に、背景は適用されません。
Margins are always transparent.(transparent:透明な,すけて見える)

 ■ マージンの相殺(Collapsing margins)

相互に隣り合っているか入れ子関係にある複数のボックス間において、 間にパディングもしくはボーダー領域を挟まずに隣接するマージン同士は、結合して1つのマージンになります。

adjoining margins (no padding or border areas separate them) of two or more boxes (which may be next to one another or nested) combine to form a single margin.


例 1

二つのボックスが隣接する場合

Box A の下マージンと Box B の上マージンは パディングやボーダーを挟まずに隣接しているので相殺されます。

例 2

三つのボックスが隣接する場合

図(左)の場合
例 1 同様、Box A の下マージンと Box B の上マージン、Box B の下マージンと Box C の上マージンが相殺されます。

図(中)の場合
これも、Box A の下マージンと Box B の上マージン、Box B の下マージンと Box C の上マージンが相殺されます。

図(右)の場合
Box A の下マージン、Box B の上マージンと下マージン、Box C の上マージンがパディングやボーダーを挟まずに隣接しています。 よってこれらすべてのマージンが相殺されます。

相殺結果

相殺結果

例 3

二つのボックスが入れ子の場合

Box A(親)の下マージンと Box B(子)の下マージンは Box A(親)のパディングとボーダーを挟んで隣接しています。 よって相殺されません。逆にいえば、親にパディングもボーダーもなければ相殺されます。

 ■ 相殺後のマージン

親のボーダー上辺一致した例
 ■ ブラウザによる違い 1

	<div style="clear:both; width:100%">
		<p>この後、19時半頃から20時過ぎまで土砂降りの雨。</p>
	</div>

	<div style=" float:left; width:350px; text-align:center; margin:10px">
		<img src="photo/flower.jpg" width="300" height="225" alt="卯の花">
	</div>

	<div style="text-align:left; margin:10px">
		<img src="photo/flower.jpg" width="225" height="300" alt="卯の花">
	</div>
	

IE 6 では段差なく並びますが、Firefox 2 ではずれが生じます。

左右の写真の上端が揃っていない例

Firefox では <p> が暗示的にマージン(数px)を持っているためと考えられます。 左の写真はフロートを指定しているので上マージンは相殺されず10+数px。 右の写真は通常のブロックなので上マージンは相殺され10px。その差、数px がずれます。 よって、先行するブロックがマージンを持つ場合、その後にフロートを指定したブロックと通常のブロックを並べるときには、 該当箇所のマージンをゼロにする <p style="margin:0px"> などの対応が必要となります。 この例では <p> のマージンが親のマージンと相殺されないよう padding を設定すれば、

	<div style="clear:both; width:100%; padding:1px">
	
親のマージンはゼロのままとなり二つの画像はずれることなく並ぶことになります。

 ■ ブラウザによる違い 2

	<div style=" float:left; width:350px; text-align:center; margin:10px">
		<img src="photo/flower.jpg" width="300" height="225" alt="卯の花">
	</div>

	<div style="text-align:left; margin:10px">
		<img src="photo/flower.jpg" width="225" height="300" alt="卯の花">
	</div>

	<div style="clear:both; width:100%"></div>

	<div style=" float:left; width:350px; text-align:center; margin:10px">
		<img src="photo/flower.jpg" width="225" height="300" alt="卯の花">
	</div>

	<div style="text-align:left; margin:10px">
		<img src="photo/flower.jpg" width="225" height="300" alt="卯の花">
	</div>
	

これも IE 6 では段差なく並びますが、Firefox 2 ではずれが生じます。

左右の写真の上端が揃っていない例

<div style="clear:both; width:100%"></div> は、空要素であるため、 上下マージン(= 0px)も相殺されて高さゼロにまとまります。 → 上右の写真のマージンと相殺されてマージンは 10px。 → さらに、上右の写真と下右の写真が相殺されてマージンは 10px。
[参考:マージン A がマージン B と相殺される場合、マージン B はマージン A と相殺されるとも言える。]
ところが、下左の写真はフロートが指定されているため、マージンは相殺されず上マージンは合計 20px。 この差、10pxがずれます。このケースは Firefox の解釈が正しいと思われます。
よって、直前のブロックにマージンがなくても、そのブロックが空要素なら注意が必要です。 空要素に先行するブロックのマージンと相殺されてマージンを持つ(先行するブロックのマージンが効く)場合があるからです。 回避するためには、空要素とならないよう内容に &nbsp;(空白)を指定したり、padding を設定します。

	<div style="clear:both; width:100%; padding:1px">
	

Home