Home > Article > Web Front-end > An in-depth analysis of CSS layout and BFC
There are some concepts in CSS layout that, once you understand them, can really improve your CSS layout abilities. This article is about Block Formatting Context (BFC). You've probably never heard of this term, but if you've ever done layout with CSS you probably know what it is. Understanding what BFC is, how it works, and how to create a BFC is very useful and can help. You understand how layout works in CSS.
(Recommended tutorial: CSS Tutorial)
In this article, what is BFC is explained through familiar examples. Then specify a new value for display
, which only makes sense if you understand what BFC
is and why you need it.
In the CSS rendering of a Web page, the block-level formatting context (Block Fromatting Context) is laid out according to the block-level box. The W3C defines BFC as follows:
Floated elements and absolutely positioned elements, block-level containers that are not block-level boxes (such as inline-blocks, table-cells, and table-captions), and overflow values other than " "visiable" block-level boxes will create new BFCs (block-level format contexts) for their contents.
BFC is an independent layout environment in which the element layout is not affected by the outside world. In a BFC, block boxes and line boxes (line boxes are composed of all inline elements in a row) Will be arranged vertically along the border of its parent element.
The behavior of a block formatting context (BFC) is easy to understand with a simple float
example. In the example below, I have a box with an image floating to the left and some text. If we have enough text, it will wrap around the floating image and border, and then around the entire area.
// html <p> </p><p>I am a floated element.</p> I am text inside the outer box. // css .outer { border: 5px dotted rgb(214,129,137); border-radius: 5px; width: 450px; padding: 10px; margin-bottom: 40px; } .float { padding: 10px; border: 5px solid rgba(214,129,137,.4); border-radius: 5px; background-color: rgba(233,78,119,.4); color: #fff; float: left; width: 200px; margin: 0 20px 0 0; }
If I remove some of the text, there isn't enough content to surround the image, and since the float is taken out of the document flow, the border goes up and over below the image, up to the height of the text.
This is because when we float an element, the width of the box where the text is located remains the same and is shortened to make room for the floating element. is the line box for the text. That's why the background and border appear behind the float.
We usually have two ways to solve this layout problem. One way is to use the clearfix hack, which does it by inserting an element below the text and image and setting it to clear:both
. An alternative is to use the overflow
attribute with a value other than the default visible
.
.outer { overflow: auto; }
View the demo: https://codepen.io/anon/embed/XzYWZj?height=500&theme-id=0&slug-hash=XzYWZj&user=&default- The reason tab=
overflow
works this way is that using any value other than the initial value of visible
creates a block formatting context, One feature of BFC is that it contains floats.
You can think of BFC as a mini layout within the page. Once an element creates a BFC, it contains all content. As we can see, this includes floated elements that no longer stick out from the bottom of the box. BFC also leads to some other useful behaviors.
Understanding margin merging is another underrated CSS skill. In the next example, assume you have a p
with a gray background color.
This p
contains two tags p
. The margin-bottom
of the outer p element is 40 pixels, and the top and bottom margin
of the label p
are both 20 pixels.
// html <p> </p><p>I am paragraph one and I have a margin top and bottom of 20px;</p> <p>I am paragraph one and I have a margin top and bottom of 20px;</p> // css .outer { background-color: #ccc; margin: 0 0 40px 0; } p { padding: 0; margin: 20px 0 20px 0; background-color: rgb(233,78,119); color: #fff; }
Because there is nothing between the p
element's margin and the margin on the outer p
, the two collapse, so p
End up flush with the top and bottom of p
. We don't see any gray above and below p
.
In CSS, the margins of two adjacent boxes (which may be brothers or ancestors) can be combined into a single margin. This way of merging margins is called collapsing, and the resulting margins are called collapsed margins. The folded result is calculated according to the following rules:
产生折叠的必备条件:margin必须是邻接的!
如果我们把盒子设为 BFC,它现在包含了标签 p
和它们的边距,这样它们就不会折叠,我们可以看到边距后面容器的灰色背景。
.outer { background-color: #ccc; margin: 0 0 40px 0; overflow: auto; }
查看演示:https://codepen.io/anon/embed/YEvzRv?height=500&theme-id=0&slug-hash=YEvzRv&user=&default-tab=
再一次,BFC 的工作是把东西装在盒子里,防止它们从盒子里跑出来。
你将熟悉 BFC 的这种行为,因为使用浮动的任何列类型布局都是这样工作的。如果一个项目创建了一个 BFC,那么该项目将不会包裹任何浮动元素。在下面的例子中,有如下 html 结构:
<p> </p><p>I am a floated element.</p> <p>I am text</p>
带有 float 类的项被向左浮动,因此 p
中的文本在它环绕 float
之后。
我可以通过将包裹文本的 p
设置为 BFC 来防止这种包裹行为。
.text { overflow: auto; }
这实际上是我们创建具有多个列的浮动布局的方法。浮动项还为该项创建了一个 BFC,因此,如果右边的列比左边的列高,那么我们的列就不会相互环绕。
查看演示:https://codepen.io/anon/embed/qVKEpJ?height=500&theme-id=0&slug-hash=qVKEpJ&user=&default-tab=
如果我们创建一个占满整个容器宽度的多列布局,在某些浏览器中最后一列有时候会掉到下一行。这可能是因为浏览器四舍五入了列宽从而所有列的总宽度会超出容器。但如果我们在多列布局中的最后一列里创建一个新的BFC,它将总是占据其他列先占位完毕后剩下的空间。
例如:
<p> </p><p>column 1</p> <p>column 2</p> <p>column 3</p>
对应的CSS:
.column { width: 31.33%; background-color: green; float: left; margin: 0 1%; } .column:last-child { float: none; }
未创建 BFC 之前:
添加以下样式创建一个 BFC:
.column:last-child { float: none; overflow: hidden; }
现在尽管盒子的宽度稍有改变,但布局不会打破。当然,对多列布局来说这不一定是个好办法,但能避免最后一列下掉。这个问题上弹性盒或许是个更好的解决方案,但这个办法可以用来说明元素在这些环境下的行为。
除了使用 overflow
创建 BFC 外,其他一些 CSS 属性还创建 BFC。正如我们所看到的,浮动元素创建了 BFC。你的浮动项将包含它里面的任何东西。
使用以下方式都能创建 BFC
使用overflow或其他的方法创建BFC时会有两个问题。首先,这些方法本身是有自身的设计目的,所以在使用它们创建BFC时可能会产生副作用。例如,使用overflow创建BFC后在某些情况下可能会看到出现一个滚动条或者元素内容被裁切。
这是由于overflow属性的设计是用来让你告诉浏览器如何定义元素的溢出状态的。浏览器执行了它最基本的定义。
即使在没有任何不想要的副作用的情况下,使用 overflow
也可能会让其他开发人员感到困惑。为什么 overflow
设置为 auto
或 scroll
?最初的开发者的意图是什么?他们想要这个组件上的滚动条吗?
最安全的做法应该是创建一个 BFC 时并不会带来任何副作用,它内部的元素都安全的呆在这个迷你布局中,这种方法不会引起任何意想不到的问题,也可以理解开发者的意图。CSS 工作组也十分认同这种想法,所以他们定制了一个新的属性值:display:flow-root
。
flow-root 浏览器支持情况
You can use display:flow-root to safely create a BFC to solve the various problems mentioned above: wrapping floating elements, preventing margins from overlapping, and preventing surrounding floating elements.
Browser support for this attribute is currently limited. If you think this attribute value is very convenient, please vote to let Edge support it. But anyway, you should now understand what BFC is, and how to use overflow or other methods to wrap floats, and know that BFC can prevent elements from surrounding floated elements. If you want to use elastic or grid layout, you can do it in some different ways. Support their browsers to use these features of BFC for downgrade processing.
Understanding how browsers lay out web pages is very basic. While it may seem inconsequential at times, these little things can speed up the time it takes to create and debug CSS layouts.
The above is the detailed content of An in-depth analysis of CSS layout and BFC. For more information, please follow other related articles on the PHP Chinese website!