CSSでmarginの相殺を起こらなくする方法

ウェブページのレイアウトで、適度に余白を入れるのは重要ですね。そして、余白を作るためにCSSのmarginプロパティを指定するのが一般的です。

でも、marginプロパティって意外とやっかいだったりします。marginの相殺を念頭に入れないと、想定したよりも大きい余白や小さい余白が出来ちゃったりするんですよね。

IE7をサポートする場合、hasLayoutによって、marginが相殺されたり、されなかったりします。

そこで、marginの相殺自体を起こらなくする方法を紹介します。

そもそも、marginの相殺が起こるケースってどういうケースかと言えば、次の2つがあります。

  • margin-topとmargin-bottomを指定された要素が隣接している
  • margin-top(margin-bottom)を指定された要素が入れ子になっている

つまり、この状態を作らなければ、marginの相殺は起こらないことになります。そこで、試してほしいのがこれです。

*+p {
  margin-top: 1em;
}

全称セレクタと隣接セレクタを組み合わせて「何らかの要素の次にある要素」にだけmargin-topを指定すればいいんです。

これで、隣接する要素の間にだけmarginを指定することができます。リストを横並びにしたときなんかにも応用できます。

li {
  float: left;
}
li+li {
  margin-left: 1em;
}

次に、ある要素の前後に適度な余白を作りたい場合ってありますよね?

例えば、HTML5のセクショニング・コンテンツの要素(section要素・nav要素・article要素・aside要素)を使った以下のようなソースの場合です。

<p>段落</p>
<!--ここの余白を少し広めにとりたい(泣)-->
<section>
  <h1>見出し</h1>
  <p>段落</p>
</section>
<!--ここの余白を少し広めにとりたい(泣)-->
<p>段落</p>

こういうケースでmarginの相殺を起こらないようにするにはこれ。

section, section+* {
  margin-top: 2em;
}

「余白をとりたい要素とその次にある要素」にmargin-topを指定すればいいんです。

marginの相殺で悩んだら試してみてください。

【追記】:first-child を使った書き方もできますね。

p {
  margin-top: 1em;
}
p:first-child {
  margin-top: 0;
}
li {
  margin-left: 1em;
  float: left;
}
li:first-child {
  margin-left: 0;
}