翻訳: CSS のブロックレベルの書式設定コンテキストを理解する
原著者: Ritesh Kumar
原記事: http://www.sitepoint.com/ Understanding-block-formatting-contexts-in-cs...
翻訳者: HaoyCn
日付: 2015年8月9日
ブロック書式設定コンテキストは、Web ページの CSS 視覚レンダリングの一部であり、ブロック ボックスのレイアウトを決定するために使用されます。これは、ポジショニング スキームの通常のフローに属します。 W3C によると:
フローティング、絶対配置要素 (位置は絶対または固定)、インライン ブロック要素、display:inline-block、表セル display:table-cell、表タイトル display:table-caption およびオーバーフロー属性値要素表示されない場合 (値がウィンドウのビューポートに伝播される場合を除く)、新しいブロックレベルの書式設定コンテキストが作成されます。
上記の引用は、BFC がどのように形成されるかをほぼ要約しています。しかし、別の、よりわかりやすい方法で再定義してみましょう。 BFC は、次の条件の少なくとも 1 つを満たす HTML ボックスです:
BFC は明示的にトリガーできます。これを作成したい場合は、上記の CSS スタイルのいずれかを追加するだけです。
たとえば、次の HTML を見てください:
<div class="container"> Some Content here</div>
新しい BFC は、overflow:scroll、overflow:hidden、display:flex、float:left、display などの必要な CSS スタイルをコンテナに追加することで作成できます。 : テーブル。上記の条件により BFC が発生する可能性がありますが、次のような他の影響も生じます。
したがって、BFC を作成したい場合は常に、ニーズに基づいて最適なスタイルを選択する必要があります。一貫性を保つために、この記事のすべての例で overflow: hidden を使用します。
.container { overflow: hidden;}
overflow: hidden 以外の他のスタイルも自由に使用できます。
W3C 仕様:
BFC コンテキストでは、各ボックスの左外側は、それを含むブロックの左側に近くなります (右から左の形式では、右外側はボックスが新しい BFC を作成しない限り (ボックス内のライン ボックスはフロートのせいで狭くなる可能性がありますが)、フロートがあっても (ボックス内のライン ボックスはフロートのせいで狭くなる可能性があります)、ボックスの側面は右の包含ブロックに近いです)。フロートに)。
簡単に言えば、上の図に示すように、BFC に属するボックスはすべて左揃え (左から右の形式) であり、その外側の左辺は、それを含むブロックの左辺と接しています。 。最後のボックスでは、左側に浮動要素 (茶色) がありますが、別の要素 (緑色) がまだ包含ブロックの左側に接続されていることがわかります。これがどのように発生するかについては、以下のテキストの折り返しに関するセクションで説明します。
通常のフローでは、ボックスは含まれるブロックの上から 1 つずつ垂直に配置されます。 2 つの兄弟ボックス間の垂直方向の間隔は、それぞれのマージンによって決まりますが、マージンの合計では決まりません。
理解を容易にするために、例を見てみましょう。
上の図では、赤いボックス (div) に 2 つの兄弟要素 (p) が含まれており、BFC が作成されています。
<div class="container"> <p>Sibling 1</p> <p>Sibling 2</p></div>
対応する CSS は次のとおりです:
.container { background-color: red; overflow: hidden; /* creates a block formatting context */}p { background-color: lightgreen; margin: 10px 0;}
理論的には、2 つの兄弟要素間のマージンはそれらのマージンの合計 (20px) である必要がありますが、実際には 10px です。これはマージンの縮小として知られています。兄弟要素のマージンが異なる場合は、最大のマージンが使用されます。
BFC のマージンの折り込みに関する上記の状況を説明した後、今すぐ折り畳むのを避けると言うのは少し混乱するかもしれません。ただし、心に留めておく必要があるのは、隣接するブロック レベル ボックス (兄弟) 間の垂直方向のマージンが崩れるのは、それらが同じ BFC 内にある場合のみであるということです。異なる BFC に属している場合、それらは折りたたまれません。したがって、新しい BFC を作成することで、マージンの崩壊を回避できます。
先ほどの例に 3 番目の兄弟要素を追加しましょう。HTML は次のようになります:
<div class="container"> <p>Sibling 1</p> <p>Sibling 2</p> <p>Sibling 3</p></div>
CSS は次のようになります:
.container { background-color: red; overflow: hidden; /* creates a block formatting context */}p { background-color: lightgreen; margin: 10px 0;}
結果は上記と同じです。つまり、折りたたみは依然として発生し、3 つの兄弟要素は分離されます。 垂直距離は10pxです。これは、3 つの p タグがすべて同じ BFC に属しているためです。
ここで、3 番目の兄弟要素を変更して、新しい BFC の一部になります。 HTML は次のようになります:
<div class="container"> <p>Sibling 1</p> <p>Sibling 2</p> <div class="newBFC"> <p>Sibling 3</p> </div></div>
CSS:
.container { background-color: red; overflow: hidden; /* creates a block formatting context */}p { margin: 10px 0; background-color: lightgreen;}.newBFC { overflow: hidden; /* creates new block formatting context */}
出力結果は異なります:
2 番目と 3 番目の兄弟要素が異なる BFC に属しているため、マージンの崩壊は発生しなくなります。
BFC可以包含浮动。我们经常遇到容器中含有浮动元素的情况。这种情况下容器元素没有高度并且其浮动子元素脱离了网页的常规流。我们通常用清除浮动解决这个问题,最普遍的做法就是使用伪元素。但我们也可以通过创建一个BFC来解决问题。
看个例子:
<div class="container"> <div>Sibling</div> <div>Sibling</div></div>
CSS:
.container { background-color: green;}.container div { float: left; background-color: lightgreen; margin: 10px;}
在上面这个例子中,容器没有任何高度,并且它包不住浮动子元素。为解决此问题,我们通过添加 overflow: hidden 来在容器中创建一个新的BFC。修改后的CSS成了:
.container { overflow: hidden; /* creates block formatting context */ background-color: green;}.container div { float: left; background-color: lightgreen; margin: 10px;}
现在容器可以包住浮动子元素,并且其高度会扩展至包住其子元素,在这个新的BFC中浮动元素又回归到页面的常规流之中了。
有时候浮动DIV旁边的文本会环绕它(如下图1所示)而这种情况有时候并不如我们所愿,我们想要下图2的效果。要解决这个问题,我们可以用外边距,但也可以用BFC。
首先让我们弄明白为何文字会环绕。要理解这个我们必须明白,当存在元素浮动的时候,盒模型如何工作。这就是我早先讨论BFC中对齐时候的遗留问题。我们通过下图来看图1到底发生了什么。
假设HTML是:
<div class="container"> <div class="floated"> Floated div </div> <p> Quae hic ut ab perferendis sit quod architecto, dolor debitis quam rem provident aspernatur tempora expedita. </p></div>
上图整个黑色区域表示 p 元素,如我们所见,p 元素没有移位但它叠在了浮动元素之下,而p元素的行盒子(即文本行)却移位了,行盒子水平变窄来给浮动元素腾出了空间。
随着文本的增加,最后文本将环绕在浮动元素之下,因为那时候行盒子不再需要移位,也就成了图1的样子。这就是为什么即便有浮动元素,段落仍紧贴包含块的左侧,而行盒子会变窄来给浮动元素腾位子。
如果我们能位移整个 p 元素,这个环绕问题也就迎刃而解了。
在说解决方案之前,我们再回顾下W3C规范:
在BFC上下文中,每个盒子的左外侧紧贴包含块的左侧(从右到左的格式里,则为盒子右外侧紧贴包含块右侧),甚至有浮动也是如此(尽管盒子里的行盒子 Line Box 可能由于浮动而变窄),除非盒子创建了一个新的BFC(在这种情况下盒子本身可能由于浮动而变窄)。
据此,如果 p 元素创建一个新的BFC那它就不会再紧贴包含块的左侧了。给 p 元素添加 overflow: hidden 就能轻而易举地办到。这解决了文本环绕浮动对象的问题。
如果我们创建一个占满整个容器宽度的多列布局,在某些浏览器中最后一列有时候会掉到下一行。这可能是因为浏览器四舍五入了列宽从而所有列的总宽度会超出容器。但如果我们在多列布局中的最后一列里创建一个新的BFC,它将总是占据其他列先占位完毕后剩下的空间。
我们来举个三列布局的例子:
这是HTML:
<div class="container"> <div class="column">column 1</div> <div class="column">column 2</div> <div class="column">column 3</div></div>
CSS:
.column { width: 31.33%; background-color: green; float: left; margin: 0 1%;}/* Establishing a new block formatting context in the last column */.column:last-child { float: none;overflow: hidden; }
现在尽管盒子的宽度稍有改变,但布局不会打破。当然,对多列布局来说这不一定是个好办法,但能避免最后一列下掉。这个问题上弹性盒或许是个更好的解决方案,但这个办法可以用来说明元素在这些环境下的行为。
我希望本文已经向你展示了BFC的特性以及BFC是如何影响页面上的元素的视图定位的。展示其用法的例子应该有让BFC显得更透彻一些。
如果你有任何想要补充的,请在评论里留言。如果你想更深入了解的话,一定得去回顾W3C对这个话题的详述。
本文中提及的浮动与行盒子变窄问题深入探讨,可以参看博文:http://www.zhangxinxu.com/wordpress/?p=583
转载本文亦请同时注明原出处(见本文顶部)。如您认可本文翻译,欢迎推荐或收藏,谢谢!