web-dev-qa-db-ja.com

div内の浮動要素は、divの外側に浮動します。どうして?

あなたがdivを持っているとしましょう、私がそれの中にものを入れるとき、あなたがそれを緑色に着色して、そしてそれに一定の幅を与えると言いなさい、私の場合imgと別のdiv。その考えは、コンテナーdivの内容がコンテナーdivを引き伸ばし、内容の背景になるということです。しかし、これを実行すると、含まれているdivは非浮動オブジェクトに合わせて縮小され、浮動オブジェクトは完全に外に出るか、半分に半分になるかのいずれかになり、大きなdivのサイズには影響しません。

どうしてこれなの?足りないものはありますか。フローティング項目を入れて、含まれているdivの高さを伸ばすにはどうすればよいですか。

241
DavidR

最も簡単な方法は、親のdivにoverflow:hiddenを置き、高さを指定しないことです。

#parent { overflow: hidden }

もう1つの方法は、親divも浮動小数点数にすることです。

#parent { float: left; width: 100% }

別の方法では明確な要素を使用します。

<div class="parent">
   <img class="floated_child" src="..." />
   <span class="clear"></span>
</div>

CSS

span.clear { clear: left; display: block; }
361
Doug Neiner

理由

問題は、浮動要素が out-of-flow であるということです。

フロート、絶対配置、またはルート要素である場合、要素はフロー外でoutと呼ばれます。

したがって、それらは in-flow 要素のように周囲の要素に影響を与えません。

これは 9.5 Floats で説明されています:

フロートはフロー内にないため、フロートボックスの前後に作成された非配置ブロックボックスは、フロートが存在しないかのように垂直に流れます。ただし、フロートの横に作成された現在および後続の行ボックスは、フロートのマージンボックス用のスペースを確保するために必要に応じて短縮されます。

enter image description here

html {
  width: 550px;
  border: 1px solid;
}
body {
  font-family: sans-serif;
  color: rgba(0,0,0,.15);
}
body:after {
  content: '';
  display: block;
  clear: both;
}
div {
  position: relative;
}
div:after {
  font-size: 200%;
  position: absolute;
  left: 0;
  right: 0;
  top: 0;
  text-align: center;
}
.block-sibling {
  border: 3px solid green;
}
.block-sibling:after {
  content: 'Block sibling';
  color: green;
}
.float {
  float: left;
  border: 3px solid red;
  height: 90px;
  width: 150px;
  z-index: 1;
}
.float:after {
  content: 'Float';
  color: red;
}
<div class="float"></div>
<div class="block-sibling">
  Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec a diam lectus. Sed sit amet ipsum mauris. Maecenas congue ligula ac quam viverra nec consectetur ante hendrerit. Donec et mollis dolor. Praesent et diam eget libero egestas mattis sit amet vitae augue. Nam tincidunt congue enim, ut porta lorem lacinia consectetur. Donec ut libero sed arcu vehicula ultricies a non tortor.
</div>

これは 10.6高さとマージンの計算 でも指定されています。 "通常"ブロック の場合、

通常のフローの子のみが考慮されます(つまり、フローティングボックスと絶対配置ボックスは無視されます[…])

enter image description here

html {
  width: 550px;
  border: 1px solid;
}
body {
  font-family: sans-serif;
  color: rgba(0,0,0,.15);
}
body:after {
  content: '';
  display: block;
  clear: both;
}
div {
  position: relative;
}
div:after {
  font-size: 200%;
  position: absolute;
  left: 0;
  right: 0;
  top: 0;
  text-align: center;
}
.block-parent {
  border: 3px solid blue;
}
.block-parent:after {
  content: 'Block parent';
  color: blue;
}
.float {
  float: left;
  border: 3px solid red;
  height: 130px;
  width: 150px;
}
.float:after {
  content: 'Float';
  color: red;
}
<div class="block-parent">
  <div class="float"></div>
  Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec a diam lectus. Sed sit amet ipsum mauris. Maecenas congue ligula ac quam viverra nec consectetur ante hendrerit.
</div>

ハッキーソリューション:クリアランス

この問題を解決する方法は、すべてのフロートの下にインフロー要素を強制的に配置することです。次に、親の高さが大きくなり、その要素がラップされます(したがって、フロートも)。

これは clearプロパティ を使用して実現できます。

このプロパティは、要素のボックスのどの辺が、以前のフローティングボックスに隣接するnotかを示します。

enter image description here

html {
  width: 550px;
  border: 1px solid;
}
body {
  font-family: sans-serif;
  color: rgba(0,0,0,.15);
}
body:after {
  content: '';
  display: block;
  clear: both;
}
div {
  position: relative;
}
div:after {
  font-size: 200%;
  position: absolute;
  left: 0;
  right: 0;
  top: 0;
  text-align: center;
}
.block-parent {
  border: 3px solid blue;
}
.block-parent:after {
  content: 'Block parent';
  color: blue;
}
.float {
  float: left;
  border: 3px solid red;
  height: 84px;
  width: 150px;
}
.float:after {
  content: 'Float';
  color: red;
}
.clear {
  clear: both;
  text-align: center;
  height: 37px;
  border: 3px dashed pink;
}
.clear:after {
  position: static;
  content: 'Block sibling with clearance';
  color: pink;
}
<div class="block-parent">
  <div class="float"></div>
  Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec a diam lectus. Sed sit amet ipsum mauris. Maecenas congue ligula ac quam viverra.
  <div class="clear"></div>
</div>

したがって、解決策は、clear: bothを空の最後の兄弟として空の要素を追加することです

<div style="clear: both"></div>

ただし、それはセマンティックではありません。そのため、親の最後に pseudo-element を生成する方が適切です。

.clearfix::after {
  clear: both;
  display: block;
}

このアプローチには複数のバリエーションがあります。古いブラウザをサポートするために非推奨の単一コロン構文:afterを使用するか、他の ブロックレベル を使用してdisplay: tableのように表示します。

解決策:BFCルート

最初に定義された問題のある動作には例外があります。ブロック要素が Block Formatting Context (BFCルートである)を確立すると、その浮動コンテンツもラップします。

10.6.7ブロックフォーマットコンテキストルートの「自動」高さ によると、

エレメントの下部マージンEdgeがエレメントの下部コンテンツEdgeの下にある浮動子孫がある場合、それらのエッジを含むように高さが増加します。

enter image description here

html {
  width: 550px;
  border: 1px solid;
}
body {
  font-family: sans-serif;
  color: rgba(0,0,0,.15);
}
body:after {
  content: '';
  display: block;
  clear: both;
}
div {
  position: relative;
}
div:after {
  font-size: 200%;
  position: absolute;
  left: 0;
  right: 0;
  top: 0;
  text-align: center;
}
.block-parent {
  border: 3px solid blue;
}
.block-parent.bfc-root:after {
  content: 'BFC parent';
  color: blue;
}
.float {
  float: left;
  border: 3px solid red;
  height: 127px;
  width: 150px;
}
.float:after {
  content: 'Float';
  color: red;
}
.bfc-root {
  overflow: hidden;
}
<div class="block-parent bfc-root">
  <div class="float"></div>
  Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec a diam lectus. Sed sit amet ipsum mauris. Maecenas congue ligula ac quam viverra nec consectetur ante hendrerit.
</div>

さらに、 9.5 Floats で説明したように、BFCルートは次の理由からも有用です。

テーブルの境界ボックス、ブロックレベルの置換要素、または新しいブロックフォーマッティングコンテキストを確立する通常フロー内の要素[…]は、要素自体と同じブロックフォーマッティングコンテキストのフロートのマージンボックスと重なってはなりません。 。

enter image description here

html {
  width: 550px;
  border: 1px solid;
}
body {
  font-family: sans-serif;
  color: rgba(0,0,0,.15);
}
body:after {
  content: '';
  display: block;
  clear: both;
}
div {
  position: relative;
}
div:after {
  font-size: 200%;
  position: absolute;
  left: 0;
  right: 0;
  top: 0;
  text-align: center;
}
.block-sibling {
  border: 3px solid green;
}
.block-sibling.bfc-root:after {
  content: 'BFC sibling';
  color: green;
}
.float {
  float: left;
  border: 3px solid red;
  height: 90px;
  width: 150px;
  z-index: 1;
}
.float:after {
  content: 'Float';
  color: red;
}
.bfc-root {
  overflow: hidden;
}
<div class="float"></div>
<div class="block-sibling bfc-root">
  Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec a diam lectus. Sed sit amet ipsum mauris. Maecenas congue ligula ac quam viverra nec consectetur ante hendrerit. Donec et mollis dolor. Praesent et diam eget libero egestas mattis sit amet vitae augue. Nam tincidunt congue enim, ut porta lorem lacinia consectetur.
</div>

ブロックフォーマットコンテキストは、

  • overflowvisible以外のブロックボックス、例: hidden

    .bfc-root {
      overflow: hidden;
      /* display: block; */
    }
    
  • ブロックボックスではないブロックコンテナー: displayinline-blocktable-cell、またはtable-captionに設定されている場合。

    .bfc-root {
      display: inline-block;
    }
    
  • フローティング要素: floatleftまたはrightに設定されている場合。

    .bfc-root {
      float: left;
    }
    
  • 絶対位置の要素: positionabsoluteまたはfixedに設定されている場合。

    .bfc-root {
      position: absolute;
    }
    

これらは、オーバーフローするコンテンツのクリッピング、 shrink-to-fit アルゴリズムを使用した自動幅の計算、またはアウトオブフローになるなど、望ましくない副次効果を持つ場合があることに注意してください。そのため、問題は、BFCを確立する目に見えるオーバーフローを伴うインフローブロックレベル要素を持つことができないことです。

ディスプレイL これらの問題に対処します。

flow および flow-root を作成しました 内部表示タイプ フローレイアウトをより適切に表現します 表示タイプ および明示的なスイッチを作成します要素を BFC rootにします。 (これにより、::after { clear: both; }overflow: hidden […]のようなハックの必要がなくなります。)

残念ながら、ブラウザはまだサポートされていません。最終的には使用できるかもしれません

.bfc-root {
  display: flow-root;
}
143
Oriol

浮動div(s)divに入れ、CSSでoverflow:hidden;を渡します
それはうまくいくでしょう。

19
Nad

W3Schools推奨事項:

overflow: autoを親要素に置くと、要素の余白を含む背景全体を「色付け」します。浮動要素もボーダーの内側に留まります。

http://www.w3schools.com/css/tryit.asp?filename=trycss_layout_clearfix

12
mggluscevic

欠けているものは何もありません。 Floatは、(たとえば)いくつかの段落のテキストの横に画像を配置したい場合に適しています。そのため、テキストは画像の周囲を流れます。テキストがコンテナーを "引き伸ばした"場合、それは起こりません。最初の段落が終わり、次に次の段落が画像の下から始まります(おそらく数百ピクセル下)。

そしてそれが、あなたが自分の結果を手に入れている理由です。

11

場合によっては、つまりwhen(if)要素を同じ「行」に流すためにfloatを使用している場合、

display: inline-block;

の代わりに

float: left;

そうでなければ、CSSの動作を行うために要素を必要とするために穀物に反する可能性があるとしても、最後にclear要素を使用すると動作します。

8
LSerni

より現代的なアプローチは次のとおりです。

.parent {display: flow-root;} 

これ以上clearfixesはありません。

pSオーバーフローを使用して:隠された。ボックスの影を隠します。

7
pendingfox

ありがとうLSerniあなたは私のためにそれを解決しました。

これを達成するために:

+-----------------------------------------+
| +-------+                     +-------+ |
| | Text1 |                     | Text1 | |
| +-------+                     +-------+ |
|+----------------------------------------+

これをする必要があります:

<div style="overflow:auto">
    <div style="display:inline-block;float:left"> Text1 </div>
    <div style="display:inline-block;float:right"> Text2 </div>
</div>
6
Flyout

Lucasが言っているように、あなたが説明しているのはfloatプロパティの意図された振る舞いです。多くの人を混乱させるのは、CSSレイアウトモデルの欠点を補うために、floatが本来の意図された使用法をはるかに超えてプッシュされたことです。

このプロパティがどのように機能するのかを詳しく知りたい場合は、 Floatutorial をご覧ください。

4