marginとfloatの関係

marginとfloatは、密接な関係にある。floatを使いこなすには、marginの理解は必須である。


marginのかかっている要素に、floatを指定した場合

親、子に関わらずmarginを指定している要素に、floatを適用すると相殺をしなくなる。また前の記事の、widthとmargin:auto；の関係で記載したようにwidthとmarginを指定した場合のautoは、数値を自動算出する。ただし、floatが指定されると、marginのautoは、必ず数値が0になる。
margin:auto;とfloat；を指定した場合の例

<style>
div {
  margin:10px auto;
  width:300px;
  float:left;
}

.child {
  margin:10px;
  width:100px;
  height:100px;
  float:left;
}

</style>

<div>
  <div class="child"></div>
  <div class="child"></div>
  <div class="child"></div>
  <div class="child"></div>
</div>
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/533731/1def15bc-28d3-b02a-bbc5-ff30b43a1514.png)

・親か子のどちらかでもfloatを指定すると、親子での相殺が起こらない。
・floatが指定されると、margin:auto；は絶対的に0になる。
・兄弟同士にfloatが指定されていると、相殺が起こらない。

floatを使用すると、その要素のmarginはpaddingのような挙動を行う。


marginのかかっている要素に、floatが隣接している場合

floatが親、この要素にかかると相殺が発生しない。ただ、floatが隣接しているだけなら、marginとfloatで相殺が発生する。以下はその基本的な条件。

・floatに隣接
・隣接している要素に、marginが指定されている
・隣接されている要素に、floatが指定されていない

上の条件が全てではない。様々は影響により、相殺が発生する場合としない場合があるので割愛。
以下、marginとfloatと相殺の例。

<style>
img {
  float:left;
  margin:0 10px;
}
.test {
  margin-top:96px;
}
</style>

<img src="dummy.jpg" alt="" width="80" height="80" />

<img src="dummy.jpg" alt="" width="80" height="80" />
<img src="dummy.jpg" alt="" width="80" height="80" />
<div class="test">floatとmarginの相殺</div>

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/533731/ddced015-1a83-d95c-67fb-057ff15696eb.png)

上のソースをまっさらはHTMLに貼った場合、図のようにはならない。理由は、bodyと.testで親子の相殺が発生し、.testのmargin-topを、親のbodyが引き継いでしまうため。

body {
  border:1px solid #fff;
}

上のソースを追記してみる。親にborderが入ることによって、親子での相殺が発生しなくなり、図のような動きをするはず。

1つの要素にmarginとfloatが指定されていると、marginの相殺が起きない。
しかし、上の例のmarginとfloatが相殺する条件を満たしているので、図のようん動きをする。そして、この相殺はfloatを解除するclearプロパティにも関係してくる。


clearは、floatを解除するものではない。

「floatを解除する」とよく説明されるclearプロパティだが、floatに隣接してはならないかを指示するプロパティ。その挙動は、先ほどのサンプルによく似ている。
clearは、marginの相殺を抑制し、floatの底辺に要素がつくように、margin-topの値を自動調整するような振る舞いを行う。
clear: none; の場合は、通常通りに振る舞う。
以下、margin, float, clearの例である。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/533731/3d335908-e390-f4af-0d07-7694b863e3e0.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/533731/e8f00f22-36dd-d647-930e-084bd24976a0.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/533731/ccb72fc8-3294-cd06-5a69-7c3b36ed6f02.png)

.clearにmargin-topに3000pxも指定している。本来なら、3000pxの間隔が空くはずだが、float:leftを指定したimgの底辺にくっついてしまっている。
これは、clearによる仕様である。clear:left;を指定したことによって、marginーtopが自動調節されて、float:left;の指定された要素の後ろにつく。さらに、float:right;を指定した.rightの底辺（marginを含む
）には、.clear-rightの上辺が重なっている。この場合、.rightの上辺から底辺までのmargin-topを調整しているわけではない。.clearから.rightまでの底辺までの距離で、margin-topを調整している。

なぜなら、隣接するfloatを指定した要素とmarginは、相殺関係になるが、.clearのように隣接する要素とmarginに相殺関係が発生しない場合は、そこからが出発点になる。clearとmargin-topを同時に適用すると、clearプロパティが優先されるので気をつける。


相殺の利点

ややこしい、marginだが、間隔をあけたい場合。相殺など利用することにより、クリーンなソースコードが書ける場合も多くある。レイアウトをmarginで書いたものと、paddingで書いた物を比較する。

完成するレイアウト
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/533731/5006f8dc-c62a-15eb-b861-e9a7702d75cc.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/533731/08178bd5-d363-dfb0-a59d-2a7c9a17233d.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/533731/fdd447a6-404a-be73-ffbb-3f1aeeb82d2c.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/533731/67e9307e-fd56-48f4-e9f2-15d6f0870411.png)


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/533731/11f9b856-5e13-0f37-1901-d707961ab5f9.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/533731/e9d11ed4-a7d1-1cee-a5c0-97cb13307f6a.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/533731/adb7c85c-8344-76b0-3100-54e85017a552.png)

marginの相殺を利用した物と、paddingを使ってレイアウトを組んだ物の比較。paddingを使用すると、最後の要素は、padding-bottom:0;を指定したり、classを細かく割り切ったりする。
.my10.mt20などのクラスを用意している人は、paddingのような指定を行っていることが多い。それに対して、marginの相殺を利用すると、HTML,CSSともに、短く書くことができる。
さらに適切に間隔を保つことができるので、特にCSSを指定していないimg要素がイレギュラーに入ったとしても、ある程度は容易に対処することができる。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/533731/beb5ef89-12ae-58ae-af88-2647fa3cf3b4.png)
上記サンプルは、相殺をうまく利用した例。デザインによっては、親にborderやpaddingなどを入ることにより。、相殺が使えない場合もある。しかし、相殺を理解していることで、HTMLやCSSの書く効率が変わってくる。


ブラウザのデフォルトスタイルシート

ブラウザのデフォルトスタイルシートは、marginと関連がある。h1やpなどの要素には、ブラウザで、あらかじめCSSがついている。
h1 {
  margin:0.67em 0;
  font-size:2em
}
p {
  margin:1em 0;
}
相殺を計算された上で、上下にmarginを指定されている。このスタイルしーとによって、”文章”を適切にマークアップすれば、適度な間隔を保つようになっている。
デフォルトスタイルシートを生かすように構築する場合は、相殺の考え方が大切になる。
marginは仕様とバグは、度々一緒にされることがある。
marginは、奥深く、経験もある程度必要になる。
marginのバグも回避策は多く存在するので、マスターすればCSS構築に役立ってくれるプロパティになるはず。

引用元（参考元）：https://kojika17.com/2012/08/margin-of-css.html

今回も、勉強させていただき、ありがとうございました。