前のマージンで記述されたマージルールは、CSSボックスモデルの最も複雑な部分です。コンテンツのこの部分には、クリアランス(クリアランス)、通常のフロー/インフロー(通常のフロー)、BFC(ブロックフォーマットコンテキスト)、ラインボックス(ラインボックス)、インラインボックス(インラインボックス)など、理解しにくい多くの概念が含まれているためです。 )、bidi(双方向環境)など。
CSSボックスモデルは、7つの水平属性+7つの垂直属性だけではありません。
margin
border
padding
width/height
PSは、ハイヒールの茎について考えています。「パディングだけでなく、今日のマージンも」
関連するコンテンツには、少なくとも次のものが含まれます。
コンテキストボックス与ボーダーボックス
パディング/マージン率の計算方法
背景与パディング/マージン/ボーダー
負のマージン
マージンマージ
ボックスモデルは、ビジュアルフォーマットモデルの基本単位であり、CSSレイアウトモデルの重要な部分です。
CSSボックスモデルは、ドキュメントツリー内の要素に対して生成され、ビジュアルフォーマットモデルに従ってレイアウトされた長方形のボックスを記述します。
(8ボックスモデルから引用)
したがって、ボックスモデルは、ドキュメントツリーの最上位でCSSによって確立される抽象化の最初のレベルでもあり、CSSレイアウトコントロールがドキュメント要素に直接関連する部分です。マージンの統合は、垂直フォーマットに直接影響する要因の1つです。理解する必要があります。
1.古典的なシナリオ
次の例では、UAにデフォルトのスタイルシートがなく、宣言されていないスタイル属性が仕様に従って初期値になっていると想定しています。
また、UAはCSS仕様に準拠していることを前提としています。
1.リストアイテム間のマージンをマージします
li {
margin: 8px;
}
那么列表项之间的间距是多少?
.li-case1 li {
margin: 8px;
/* 添个上内边距 */
padding-top: 1px;
}
.li-case2 li {
margin: 8px;
/* 添个下边框 */
border-bottom: 1px solid;
}
case1とcase2のリストアイテムの間隔はどれくらいですか?
2.深いネストされたマージンのマージ
/* 缩进表示对应文档结的构嵌套关系 */
div.outer,
div.container,
div.content,
div.inner {
margin: 10px;
min-width: 100px;
min-height: 100px;
}
これらの4つのネストされたdivのレンダリング結果は何ですか?
div.outer,
div.container,
div.content,
div.inner {
margin: 10px;
min-width: 100px;
min-height: 100px;
/* 添个border */
border: 1px solid;
}
それで?
div.outer,
div.container,
div.content,
div.inner {
margin: 10px;
/* 删掉min-width, min-height和border */
}
今はどう?
3.マージンとギャップの組み合わせ
div.container {
border-top: 1px solid;
background: #ccc;
margin-bottom: 60px;
}
/* 缩进表示对应文档结的构嵌套关系 */
div.float {
float: left;
width: 100px;
height: 50px;
}
div.following-float {
clear: left;
margin-top: 50px;
}
div.following-container {
color: red;
}
赤いテキストの上部と.following-floatの下部の間の距離はどれくらいですか?
div.container {
border-top: 1px solid;
background: #ccc;
margin-bottom: 60px;
}
/* 缩进表示对应文档结的构嵌套关系 */
div.float {
float: left;
width: 100px;
height: 50px;
}
div.following-float {
clear: left;
/* 把50改成49 */
margin-top: 49px;
}
div.following-container {
color: red;
}
それで?
50を0と51に変更するのはどうですか?別々に何が起こりますか?
PSデモはまだ書き始めていないので、これらの質問への答えは現時点ではまだ不明です;-)それから私たちが注意深く推測するのに十分な時間があります
2.マージ条件
どのようなマージンがマージされますか?
水平方向のマージンはマージされません。2つの特別な場合を除いて、隣接する垂直マージンがマージされます。
ルート要素ボックスの外側の余白はマージされません
ギャップのある要素の上部マージンが下部マージンに隣接している場合、そのマージンは次の兄弟(要素)の隣接するマージンとマージされますが、マージ後に親ブロックとマージされません。下マージンのマージ
No. 1スキップ、ルート要素にマージンを適用することは合理的ではありません
第2条では、「クリアランス」と呼ばれる新しい概念を紹介します。英語名はクリアランスです。クリア属性に関連しているように見えますが、実際には直感的です。クリア属性によって引き起こされる要素位置の移動によって形成されるギャップを指します。CSS仕様9ビジュアルフォーマットモデルを参照してください。2つの重要なポイントが暗示されています。
明確な属性を持っています
そして(明確な属性)要素の位置を移動しました
この2つの条件が満たされている場合、要素にはギャップがあると言われます
注:clear属性が適用されている場合、要素の実際の位置は変更されません。たとえば、要素がmargin-topを介してその位置に配置されている場合、要素自体のレイアウト位置はclear Effect位置と同じです(つまり、clear属性は余分なスペースをもたらしません)。職業、いわゆるギャップ)、ギャップはありません。逆に、clear属性を適用すると、要素の実際の位置が変化する場合、つまり、ギャップがある場合でも、要素の上のスペースの一部がclear属性によってもたらされる場合。
ギャップがあるだけでは不十分ですが、要素の上下の余白が隣接しており(つまり、要素の実際の高さが0で、パディング、境界線がない)、同時に満たされると、この要素の外側の余白の組み合わせが制限されます。次の兄弟の隣接するマージンとのみマージします。マージされた結果は、親ブロックの下マージンとマージされません。
PSここにクラシックシーン3に挑戦するチケットがありますが、それでもまだ遠いです
「隣接」の定義
2つの外側マージンが「隣接」と見なされる場合はどうなりますか?
すべてが同じブロックフォーマットコンテキストのインフローブロックレベルボックスに属します
それらを分離するためのラインボックス、ギャップ、パディング、ボーダーはありません
すべてが垂直に隣接するボックスの端(垂直に隣接するボックスの端)に属します
3つの文と4つの新しい概念、深さを優先する
ストリーム
ストリーム/アウターストリーム(流入/流出)は、位置決め要素の従来のフロースキームレイアウトかどうかを示します
最初に深さを続けます。3つのタイプの位置決めスキームがあります。
通常の流れ。ブロックフォーマット、インラインフォーマット、相対配置を含む
浮く。通常のストリームの位置から取り出して左右に移動します
絶対的なポジショニング。通常のストリームから離れて、含まれているブロックに従ってその位置を決定します
要素にはfloat(float属性の適用値がnone)も絶対位置(position属性の適用値が絶対ではない)もなく、ルート要素ではないため、通常のフローに従ってレイアウトされ、フロー内の要素に属します。それ以外の場合は、流出要素
ブロックフォーマットコンテキスト
フロート、絶対位置の要素、ブロックボックスではないブロックコンテナ(インラインブロック、テーブルセル、テーブルキャプションなど)、および「オーバーフロー」が「表示」されていないブロックボックス(値が表示されている場合) (ビューポートに伝播する場合を除く)コンテンツの新しいブロックフォーマットコンテキストを確立します
ブロックフォーマットのコンテキストでは、ボックスは、含まれているブロックの上部から始めて、垂直方向に次々に配置されます。2つの兄弟ボックス間の垂直距離は、「マージン」属性によって決定されます
つまり、誰も新しいBFCを作成しない場合、それは現在のBFCにあります。JSスコープと同様に、すべてのユーザーはデフォルトで最も外側のスコープ(最も外側のブロックフォーマットコンテキスト)に配置されます。通常のブロックレベルのボックスに遭遇すると、ブロックフォーマットコンテキストに配置されます。特別な(フローティング、絶対配置など)に遭遇すると、など)スコープの新しいレイヤーを作成する(新しいブロックフォーマットコンテキストを作成する)だけで、その中の要素がこの内部スコープに配置されます(新しいブロックフォーマットコンテキスト)
レイアウトが完了した後、フォーマットコンテキストの観点からは、ネストされた一連のBFCであり、各BFCは、一連のブロックボックス(またはブロックレベルの要素)のレイアウトを管理する責任があります。
注:インラインフォーマットコンテキストは、異なるインラインフォーマットコンテキストを区別する意味がないため、ここでは説明しません(仕様定義では、インターラインフォーマットコンテキストに関する特別なシーンはありません)。では、新しいインラインフォーマットコンテキストはいつ作成されますか?仕様によれば、新しいインラインフォーマットコンテキストは、明示的に作成を強制できるBFCとは異なり、ブロックコンテナにインラインレベルボックスのみが含まれている場合にのみ作成されます。
PS新しいインラインフォーマットコンテキストがいつ作成されるかについての詳細は、ボックスがインラインフォーマットコンテキストをいつ確立するかを参照してください。
同じ行のボックスを含む長方形の領域は、行ボックスと呼ばれます
ラインボックスは、そこに含まれるすべてのボックスを保持するのに十分な高さです。
ラインボックスはCSSでのラインの抽象表現であり、各ライン要素は同じラインボックス内にあります。長すぎて収まらず、自動的に折り返されない場合は、次の行用に別のラインボックスが作成されます。一方、ラインボックスは純粋に抽象的な定義ではなく、幅と高さがあり、ラインレイアウトを決定するために使用されます
隣接するマージン間の「ラインフレームなし」は、
垂直方向の隣接するフレーム境界からそれらを分離するインライン要素がないこととして簡単に理解できます。
次の4つのシナリオは、外部マージンがすべて垂直方向に隣接するフレーム境界であるという状況を満たします。
ボックスの上部マージンと最初の流入子の上部マージン
ボックスの下部マージンと次のストリームの次の兄弟の上部マージン
最後のストリームの子の下マージンと、高さが「自動」として計算される親要素の下マージン
ボックスの上下の余白には、ボックスが新しいブロックフォーマットコンテキストを確立しておらず、「min-height」の計算値が0、「height」の計算値が0または「auto」であり、ストリームに子がないことが必要です。
長すぎるようです。条件を単純化して、すべての要素がストリーム内にあると仮定しましょう。
親子:親要素のマージンと長子のマージン
兄弟:要素の下マージンと右兄弟の上マージン
父と息子:Yaoerの下マージンと親要素の下マージン
自己:0高い「真空」要素の上部マージンと下部マージン
PSここでの「真空」とは、ポテトチップの真空を指します。そこに何もないか、亡命中の子供たちが連れ去られました
言い換えれば、「隣接するマージン」の位置の定義は、父と息子、兄弟と自己の3つの状況に具体的に分けられます(それ自体の上下のマージンの組み合わせは非常に独特です)
「隣接」と外側のマージンの組み合わせを再理解することで
、以前の概念の基礎が築かれました。次に、散在するポイントを統合し、最初に「隣接」を再定義します。
親子、兄弟、または要素自体のマージンは、それらが互いに接近している場合、「隣接」しています。
もう1つの重要なポイントがあります。互いに近いことです。つまり、2つの外側の余白は、3つのタイプに分けることができる「壁」によって分離されていません。
レース:両当事者はインストリームブロックレベルボックスである必要があります
信念:同じブロックフォーマットのコンテキストにいる
地域:2つの間にラインボックス、ギャップ、内側マージン、境界線はありません
この時点で、「隣接」はすでに非常に明確です。マージンマージの定義を逆にしましょう。
非ルート要素の隣接する垂直マージンがマージされます。ギャップがある場合、マージは制限されます
制限付きとは、ギャップのある要素の上部マージンと下部マージンが互いに隣接している場合、兄弟要素の外側マージンとのみマージでき、親要素の下部マージンとマージできないことを意味します。
3.合併条件の推論
マージンの合併の条件によると、 8つの推論があります。
フローティングボックスと他のボックスの間のマージンはマージされません(フローティングボックスとそのインストリームの子の間でも)
新しいブロックフォーマットコンテキストを確立する要素(たとえば、フローティングボックスや「オーバーフロー」が「表示」されていない要素)のマージンは、流入する子とマージされません。
絶対に配置されたボックスのマージンはマージされません(インストリームの子とさえも)
インラインブロックボックスの余白はマージされません(インストリームの子とさえも)
ストリーム内のブロックレベル要素の下限マージンは、兄弟(要素)にギャップがない限り、常に次のインストリームブロックレベル兄弟の上限マージンとマージされます。
ストリーム内のブロックレベル要素の上部マージンは、要素に上部境界と上部内部マージンがなく、その子にギャップがない場合、最初のインストリームブロックレベル子の上部マージンとマージされます。
「height」が「auto」で「min-height」が0のインストリームブロックレベルボックスの下マージンは、ボックスに下マージンがない場合、最後のインストリームブロックレベル子の下マージンとマージされます。マージンと下の境界線、およびその子の下マージンは、ギャップのある上マージンとマージされません
「min-height」プロパティが0で、上下の境界線も上下の内側の余白もなく、「height」が0または「auto」で、ラインボックスがない場合、ボックス自体の外側の余白もマージされます。ストリーム内のすべての子のマージン(存在する場合)がマージされます
簡略化された要約ですが、4つの項目:
非インストリーム(絶対配置またはフローティング)はマージされません
子とマージされない新しいBFC(フローティング、絶対位置の要素、ブロックボックスではないブロックコンテナ、および「オーバーフロー」が「表示」されない特定のブロックボックス)の作成をトリガーします
非ブロックレベルのボックス(インラインブロック)はマージされません
一般に、兄弟要素の下部と上部の余白、親要素と子要素の上部と下部の余白、および要素自体の上部と下部の余白がマージされます
最初の3つのポイントは「隣接する」(インストリーム、同じBFC、ブロックレベルボックス)の前提条件を対象とし、4番目のポイントは4種類の「隣接する」シーンの言い換えであり、拡張は8つの推論です。
4.マージ動作
。2つの隣接するマージンがマージされた後、結果のマージンはフォールドマージンと呼ばれます。
PS折りたたまれたマージンは、組み合わせたアクションとは別に、結果を示すために意図的に折りたたみとして変換されます
マージンマージには2つの特徴があります。
再帰:つまり、ディープマージ。一度マージした後、マージされた結果に隣接する外側のマージンをマージできるかどうかを確認し、マージできる場合はマージします
欲:最も広いマージ結果を追求します。2つのマージンの正の値が最大値を取り、2つの負の値が最大の絶対値を取ります
再帰的特性の場合、「隣接」の定義は再帰的式を拡張します。
折りたたまれたマージンは、そのマージンのいずれかの部分がそのマージンに隣接している限り、別のマージンに隣接することもできます。
貪欲はマージンのマージ結果の計算方法に関連しています。マージンは負の値を許可するため、状況はもう少し複雑です。
どちらも正の値であり、2つの最大値を直接見つけます
1つの正と1つの負、加算と合計
両方とも負です。2つの絶対値の最大値を見つけます
例えば:
ul {margin-bottom: -15px;}
/* 缩进表示对应文档结的构嵌套关系 */
li {margin-bottom: 20px;}
h1 {margin-top: -18px;}
その場合、h1と最後のliの間の垂直距離は20 + -max(| -15 |、| -18 |)= 2pxです。
正の値か負の値かに関係なく、最大値を求める原則は、マージ結果をできるだけ広くすることです(絶対値が大きい負の値は、要素のコンテンツをさらにシフトする可能性があります)。つまり、貪欲です
。5。オンライン
デモデモアドレス:http://ayqy.net/temp/margin-collapse.html
PSの回答はデモにあり、説明はソースコードにあります
参考資料
ボックスはいつインラインフォーマットコンテキストを確立しますか?:質問コメントは価値があり、インラインフォーマットコンテキストを理解するのに役立ちます
マージン崩壊とクリアランス:クリアランス的示例
マージンとギャップのマージの例:ChromeとSafariは仕様に準拠していないため、Firefoxを使用して表示します
マージンの崩壊:この記事を読んだ後、これを読む必要はありません