CSSブロックフォーマットコンテキストはどのように機能しますか?


80

CSSブロックフォーマットコンテキストはどのように機能しますか?

CSS2.1の仕様によると、ブロックフォーマットのコンテキストでは、ボックスは上から順に垂直に配置されます。これは、ブロックボックスが新しいブロックフォーマットコンテキストを確立した場合を除いて、途中にフロート要素がある場合でも発生します。ご存知のように、ブラウザがブロックフォーマットコンテキストでブロックボックスをレンダリングする場合、float要素は省略されますが、新しいブロックフォーマットコンテキストの確立が機能するのはなぜですか?

ボックス(ブロックボックスとインラインボックス)は通常のフローでどのように配置されますか?

ブロック要素がブロックボックスを生成することをどこかで読みましたが、ユーザーエージェントがボックスを描画するときにフローティング要素が無視され、コンテンツに入力するときにそれらが考慮されます。フローティング要素は他の要素のボックスの境界とオーバーラップしますが、解決策は、を使用してオーバーラップした要素の新しいブロックフォーマットコンテキストを確立することoverflow:hiddenです。

「新しいブロックフォーマットコンテキストは引き続きブロックフォーマットです」ので、ボックスを描画するときに、フローティング要素も終了しないかのように扱います。それは正しいですか、それとも「新しいブロックフォーマットコンテキスト」を誤解しましたか?

更新:その他の質問

「列スタイルのレイアウトに役立つのはこの動作です。ただし、主な用途は、「メインコンテンツ」divでフロートを停止し、実際にフロート側の列、つまりソースコードの前半に表示されるフロートをクリアすることです。」

私はその意味を理解していません、私は例を提供します、多分あなたは私を理解するでしょう。

フローティングボックスはcontaingブロックの一番上にフロートする必要があると思いました-クラスを持つdiv content。また、マークアップの早い段階でフローティングボックスが表示されている場合は、本来あるべき姿が表示されます。

これをどのように説明できますか?「ブロックフォーマットコンテキストとインラインフォーマットコンテキスト」を使用して説明できますか?


わからないことを記録する画像を追加していただけませんか?
mrk 2011年

フロートについて明示的に質問されていないことは知っていますが、この記事はWebページのフローがどのように機能するかを説明するのに非常に役立ち、これを理解するのに役立つと思います。
Niklas Wulff 2011年

回答:


126

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

フロート、絶対位置の要素、ブロックボックスではないブロックコンテナ(インラインブロック、テーブルセル、テーブルキャプションなど)、および「可視」以外の「オーバーフロー」を持つブロックボックス(その値が伝播されている場合を除く)ビューポートへ)コンテンツの新しいブロックフォーマットコンテキスト確立します。

私の大胆さで、重要なのは確立ビットです

これが意味するのは、使用する要素overflow(表示以外のもの)floatまたはinline-block..etcが、その子要素のレイアウトを担当するようになるということです。フロートであろうと折りたたみマージンであろうと、境界の親によって完全に含まれるべきであるかどうかにかかわらず、次に「含まれる」のは子要素です。

ブロックフォーマットのコンテキストでは、各ボックスの左外側の端が含まれているブロックの左端に接触します(右から左へのフォーマットの場合、右端が接触します)

上記の行の意味:

ボックスは長方形のみで不規則な形状にはできないため、これは、2つのフロート間(または1つのフロートの横)の新しいブロックフォーマットコンテキストが隣接するサイドフロートをラップしないことを意味します。内側の子ボックスは、親の左(またはRTLでは右)の端に触れるまでしか拡張できません。柱状スタイルのレイアウトに役立つのはこの動作です。ただし、これの主な用途は、たとえば「メインコンテンツ」divでフロートを停止し、実際にフロートされたサイド列、つまりソースコードの前半に表示されるフロートをクリアすることです。


フロートクリアランス

通常の状況では、floatは、表示された「列」だけでなく、ソースコード全体で以前にfloatされた以前のすべてのfloat要素をクリアすることになっています。「floatclearancespecs」からの引用は次のとおりです。

このプロパティは、要素のボックスのどの側が以前のフローティングボックスに隣接していない可能性があるかを示します。'clear'プロパティは、要素自体の内部または他のブロックフォーマットコンテキスト内のフロートを考慮しません

つまり、左列と右列がそれぞれ左と右にフロートする3列のレイアウトがあるとします。サイド列はフロートされているため、新しいブロックフォーマットコンテキストになります(フロートは新しいBFCを確立するプロパティの1つでもあることに注意してください) )、リスト要素をそれらの中に喜んでフロートさせることができ、それらはすでにソースコードでフロートを気にしないサイド列の中にすでにあるフロートのみをクリアします


メインコンテンツを新しいブロックフォーマットコンテキストにするかどうか。

これで、中央の柱を両側からマージンをとって、2つの側面の浮き柱の間にきちんと収まり、残りの幅をとることができます。これは、中央の柱が「流動的」である場合に目的の幅を取得する一般的な方法です。コンテンツdiv内でfloat / clearanceを使用する必要があるまで問題ありません(「clearfix」ハックまたはそれらを含むテンプレートを使用する場合によく発生します)

この非常に単純なコードを見てください:

それは以下を生成します:

ここに画像の説明を入力してください

一般的に、これは、罰金ですあなたは何の背景色や内部を持っていない場合は特に(メインコンテンツに)浮かぶ-予告山車は罰金(まだクリアされていない)している彼らはあなたがにそれらを除いて、おそらく何をやっているけど、彼ら、H3のトップマージンとpの下部マージンは、実際にはコンテンツdiv(明るい灰色の背景)に含まれていません。

したがって、上記のコードと同じ単純なマージンシナリオに次を追加します。

.clear-r {clear: right;}

CSSに移動し、2番目のHTMLフロートボックスを次のように変更します。

<div class="floated clear-r"> this a floated cleared box</div>

今回はこれを取得します:

ここに画像の説明を入力してください

2番目のフロートは右側をクリアしていますが、右側の列の高さ全体をクリアしています。右側の列はソースコードの前半でフロートされているため、指示どおりにクリアされます。おそらく望ましい効果ではありませんが、h3pマージンがまだ折りたたまれている(含まれていない)ことにも注意してください。


子供たちのために、ブロックフォーマットコンテキストを確立させてください!

そして最後に、メインコンテンツ列に責任を負わせます-ブロックフォーマットコンテキストになります-そのコンテンツについて:margin: 0 200px;メインコンテンツからCSSとADD overflow: hidden;を削除すると、次のようになります。

ここに画像の説明を入力してください

これはおそらくずっとあなたが起こることを期待するもののように、ノートが今フロートが含まれ、それらが適切に右側の列を無視し、また明らかであるh3pのマージンが含まれている代わりに崩壊しています。

最近のリセットの広範な使用により、マージンはあまり目立たなくなりました(そして、IEはまだそれらを完全に正しくしていません)が、中央の「メインコンテンツ」に起こったことは、それがブロックフォーマットコンテキストになり、現在その責任を負っているということです自分の子(子孫)要素。それは、同じプロパティを使用して、実際にhasLayoutのMicrosoftの初期の頃の概念に非常によく似ていますdisplay: inline-blockfloatと、overflowそれはバグなししかし..です見える以外、そしてもちろん、テーブルのセルは、常にレイアウトを持っています。)

それが少し役立つことを願っています、どんな質問でも気軽に尋ねてください!


更新:問題の詳細情報:

「しかし、ユーザーエージェントがボックスを描画するときにフローティング要素は無視され、コンテンツに入力するときにそれらを考慮に入れる」と言うとき。

はい、フロートは通常、コンテナボックスに重なっていますが、親の境界についてはどういう意味ですか?ブロック要素が描画され、フロートが含まれている場合、ブロックの親自体がフロートの下に長方形として描画されます。これは、他の子要素の「インライン匿名ボックス」または単に「ラインボックス」であり、スペースを空けるために短縮されます。フロート

このコードを取る:

これを生成します:

フロートのしくみ

親要素には実際にはfloatが含まれていないことがわかります。これは、完全にラップされていないためです。floatは単にコンテンツの上に浮かんでいます。コンテンツをdivに追加し続けると、最終的にはラップされます。p要素の(匿名の)「ラインボックス」がそれ以上短くなる必要がないため、フロートの下にあります。

段落要素に色を付けたので、実際にはフロートの下にあります。濃い灰色の背景は段落の始まりであり、白いテキストは「匿名のラインボックス」の始まりです。実際に「スペースを空けるのはそれらだけです。 "フロートの場合、特に指示しない限り(つまり、コンテキストを変更する場合)

再び上の画像を参照すると、p要素の左側をマージンする場合、「ラインボックス」(白いテキスト)はの左端にのみ触れるため、フロートの下部の下でテキストが折り返されるのを停止します。それらのコンテナ、およびpフロートを避けて、の色付きの背景を右側に移動しますが、pのフォーマットコンテキストの動作は変更されません。上記の最初の図の中央の列のように;)


clairesuzy、どうもありがとうございました!それは本当に私を大いに助けますが、私はまだいくつかの質問があります。私はそれを元の質問に追加しました。あなたが私を助けてくれることを願っています。
eileen Tao 2011

1
@eileenには2つのことが起こっています-あなたの余分な質問は最初の例で説明されていると思います..紫色のフロートボックスはコンテンツの後に表示されます。これは、ソース内にあるため、フロートは上にフロートせず、前より上に移動しますコンテンツ(上部の余白が本来あるべき位置より高くなることはありません)-左右の列もフロートボックスであり、ソースの初期にあり、紫色のフロートをクリアしようとすると、中央の列が新しいBFCになりません。ソース側のフロート列の初期の部分もクリアします。それは役に立ちますか?
clairesuzy 2011年

1
@eileenそのリンクは、ブロックレベルの要素とインラインレベルの要素を記述していますが、フォーマットのコンテキストでは基本的なことではありません。ブロック要素は常に100%の幅を取り、互いに重なり合って配置されます(デフォルト)-インライン要素は、リンクやスパンなどのように並べて配置されます。幅や高さすら取得しないため、オプションはありません。フロートされた要素は自動的にブロックレベルの要素になるため、インラインレベルをフロートする<span>と、ブロックレベルのようになります<div>
clairesuzy 2011年

1
続き..理由pの背景はフローティング要素が流れから削除されているので、本当に彼らがそこにいるかわからない、近隣の要素のようにフロートが、あるの下に行き、彼らは同じ書式コンテキストに属しているためpルックスへそれはその寸法の親コンテナです..(フロートの隣に100%幅のものを置くことができない理由です-それは100%がコンテナの100%だからです。匿名のボックスだけが最終的にフロートがそこにあることを理解します; )
clairesuzy 2011年

1
@ clairesuzy-投稿した画像が公開されました。再投稿していただけますか?
bfavaretto 2011
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.