CSSはフォーマットのコンテキストをどのように動作させますか?

CSSはフォーマットのコンテキストをどのように動作させますか?

どのようにCSS ブロック書式設定コンテキスト仕事?

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

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

ブロック要素がブロックボックスを生成する場所を読みますが、ユーザーエージェントがボックスを描画し、フローティング要素がボックスの他の要素の境界を重ねると、それらを考慮に入れると、フローティング要素が無視されますoverflow:hidden

「新しいブロック書式設定コンテキストは依然としてブロック書式設定です」ので、ボックスを描画するときに、フローティング要素も存在しないものとして扱われます。これは正しいですか、それとも私が「新しいブロック書式設定コンテキスト」を誤解していますか?

更新:さらに質問

「この動作は、柱状スタイルのレイアウトに役立つこの動作です。ただし、フロートを停止することは、「メインコンテンツ」DIVで、実際にフロートのサイドカラムをクリアすること、つまりソースコードの前に表示されるフロートをクリアすることです。」

意味が分かりません。例を挙げれば、理解してもらえるかもしれません。

.content {
  background: #eee;
  color #000;
  border: 3px solid #444;
  width: 500px;
  height: 200px;
}
.float {
  background: rgba(0, 0, 255, 0.5);
  border: 1px solid #00f;
  width: 150px;
  height: 150px;
  float: right;
}
p {
  background: #444;
  color: #fff;
}
<div class="content">
  <h3>This is a content box</h3>
  <p>It contains a left floated box, you can see the actual content div does go under the float, but that it is the &lt;h3&gt; and &lt;p&gt; <b>line boxes</b> that are shortened to make room for the float. This is normal behaviour.</p>
  <div class="float">floated box</div>
</div>

フローティング ボックスは、包含ブロック (class を持つ div) の上部に浮かぶべきだと考えましたcontent。また、フローティング ボックスがマークアップの前の方に表示されれば、私が想定しているとおりに表示されます。

.content {
  background: #eee;
  color #000;
  border: 3px solid #444;
  width: 500px;
  height: 200px;
}
.float {
  background: rgba(0, 0, 255, 0.5);
  border: 1px solid #00f;
  width: 150px;
  height: 150px;
  float: right;
}
p {
  background: #444;
  color: #fff;
}
<div class="content">
  <div class="float">floated box</div>
  <h3>This is a content box</h3>
  <p>it contains a left floated box, you can see the actual content div does go under the float, but that it is the &lt;h3&gt; and &lt;p&gt; <b>line boxes</b> that are shortened to make room for the float, this is normal behaviour</p>
</div>

これをどう説明すればいいでしょうか? 「ブロック書式コンテキストとインライン書式コンテキスト」を使って説明できますか?

ベストアンサー1

ブロック書式設定コンテキスト

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

私の大胆なのは、確立する重要な点

これが意味するのは、使用する要素overflow(表示以外)またはfloat..Tcinline-blockが子要素のレイアウトに責任を負うことです。

ブロック書式設定のコンテキストでは、各ボックスの左外縁は包含ブロックの左縁に接します(右から左への書式設定の場合は右縁が接します)。

上記の行の意味:

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


フロートクリアランス

通常の状況では、フロートは以前のすべてのフロート要素をクリアすることになっています。これは、以前はソースコード全体に浮かんでいます。

このプロパティは、要素のボックスのどの辺が前のフローティングボックスに隣接してはいけないかを示します。「clear」プロパティは、要素自体の内部のフロートや他のブロックフォーマットのコンテキストでは

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


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

これで、中央の列は、両側からマージンを設定するだけで、両側のフロート列の間にきちんと収まるように表示され、残りの幅が確保されます。これは、中央の列が「流動的」である場合に、希望する幅を得るための一般的な方法です。コンテンツ div 内でフロート/クリアランスを使用する必要があるまでは、これで問題ありません (「clearfix」ハックまたはそれを含むテンプレートを使用している場合はよくあることです)。

この非常に単純なコードを見てみましょう:

#left-col {
  border: 1px solid #000;
  width: 180px;
  float: left;
}
#right-col {
  border: 1px solid #000;
  width: 180px;
  float: right;
  height: 200px;
}
#content {
  background: #eee;
  margin: 0 200px;
}
.floated {
  float: right;
  width: 180px;
  height: 100px;
  background: #dad;
}
<div id="left-col">left column</div>
<div id="right-col">right column</div>

<div id="content">
  <h3>Main Content</h3>
  <p>Lorem ipsum etc..</p>
  <div class="floated">this a floated box</div>
  <div class="floated">this a floated box</div>
</div>

次のようなものが生成されます。

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

一般的に、これは問題ありません。特に背景色や内部(メインコンテンツ内)フロートがない場合 - フロートが問題ないことに注意してください(まだクリアされていません)彼らはおそらくあなた以外のことをしていますしかし彼らは、H3上部のマージンであり、p「底のマージン」は、実際にはコンテンツDiv(LightGreyの背景)に実際に含まれていません。

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

.clear-r {clear: right;}

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

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

#left-col {
  border: 1px solid #000;
  width: 180px;
  float: left;
}
#right-col {
  border: 1px solid #000;
  width: 180px;
  float: right;
  height: 200px;
}
#content {
  background: #eee;
  margin: 0 200px;
}
.floated {
  float: right;
  width: 180px;
  height: 100px;
  background: #dad;
}
.clear-r {
  clear: right;
}
<div id="left-col">left column</div>
<div id="right-col">right column</div>

<div id="content">
  <h3>Main Content</h3>
  <p>Lorem ipsum etc..</p>
  <div class="floated">this a floated box</div>
  <div class="floated clear-r">this a floated cleared box</div>
</div>

今回はこれが得られます:

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

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


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

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

#left-col {
  border: 1px solid #000;
  width: 180px;
  float: left;
}
#right-col {
  border: 1px solid #000;
  width: 180px;
  float: right;
  height: 200px;
}
#content {
  background: #eee;
  overflow: hidden;
}
.floated {
  float: right;
  width: 180px;
  height: 100px;
  background: #dad;
}
.clear-r {
  clear: right;
}
<div id="left-col">left column</div>
<div id="right-col">right column</div>

<div id="content">
  <h3>Main Content</h3>
  <p>Lorem ipsum etc..</p>
  <div class="floated">this a floated box</div>
  <div class="floated clear-r">this a floated cleared box</div>
</div>

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

これはおそらく、予想どおりの結果に近いでしょう。フロートが含まれ、右側の列を無視して適切にクリアされ、マージンは折りたたまれるのではなく含まれていることに注意してh3くださいp

最近はリセットが頻繁に使用されるため、余白は目立たなくなりました (IE では依然として余白が正確に表示されません)。ただし、中央の「メイン コンテンツ」はブロック フォーマット コンテキストになり、独自の子 (子孫) 要素を管理するようになりました。これは、Microsoft の初期の hasLayout の概念と非常によく似ており、同じプロパティdisplay: inline-blockfloat、およびoverflow表示以外のものを使用します。もちろん、テーブル セルには常にレイアウトがあります。ただし、バグはありません ;)


##更新: 問題に関する詳細情報:

「しかし、ユーザーエージェントがボックスを描画するときにはフローティング要素は無視され、コンテンツを埋めるときに考慮されます。」とおっしゃっていますが、

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

次のコードを見てください:

#content {
  background: #eee;
  color #000;
  border: 3px solid #444;
}
.float {
  background: rgba(0, 0, 255, 0.5);
  border: 1px solid #00f;
  width: 150px;
  height: 150px;
  float: left;
  margin: 10px;
}
p {
  background: #444;
  color: #fff;
}
<div id="content">
  <div class="float">floated box</div>
  <h3>This is a content box</h3>
  <p>it contains a left floated box, you can see the actual content div does go under the float, but that it is the &lt;h3&gt; and &lt;p&gt; <b>line boxes</b> that are shortened to make room for the float, this is normal behaviour</p>
</div>

結果は次のようになります:

フロートの仕組み

親要素には実際にフロートが含まれていないことがわかります。フローティングpコンテンツの上部 - div にコンテンツを追加し続けると、要素の (匿名の)「行ボックス」をこれ以上短くする必要がなくなるため、最終的にはフロートの下に折り返されます。

段落要素に色を付けたので、段落要素もフロートの下にあることがわかります。濃い灰色の背景は段落の開始位置で、白いテキストは「匿名の行ボックス」の開始位置です。実際には、別の指示(つまり、コンテキストの変更)がない限り、フロートのための「スペースを作る」のは段落要素だけです。

もう一度上の図を参照すると、要素の左側に余白を設定するとp、確かにフロートの下部でテキストが折り返されなくなります。これは、「行ボックス」(白いテキスト) がコンテナーの左端にのみ接触するためです。また、 の色付き背景がフロートの右側に移動してpフロートから外れますが、 の書式設定コンテキストの動作は変更されませんp。上の最初の図の中央の列のように ;)

おすすめ記事