BFC and Box Model for CSS
CSS has been used for a long time, but some of the usage is always vague, and there is no systematic and logical understanding. This time, let’s first clarify the BFC and box model in CSS, as well as some related positioning and layout properties.
How are elements laid out by default?
First, take the content of the element and place it in a separate element box, then add padding, borders, and margins around it - the box model we saw earlier.
By default, the content width of a block-level element is 100% of its parent element, and its height is the same as its content height. The height and width of the internal connection element is the same as the content. You cannot set the height and width of the internal connection element — they are just placed in the content of the block-level element. If you want to control the size of the internal connection element, you need to set display: block; for the element (alternatively, display: inline-block; inline-block mixes the properties of inline and block.)
This explains the layout of individual elements, but how do elements affect each other? Normal layout flow (mentioned in the introduction to layout) is a system for placing and organizing elements within the browser viewport. By default, block-level elements are placed in * block flow direction * based on the writing order of their parent elements (default: horizontal-tb) — each block-level element will have another line below the previous element, they will be separated by a set margin. In English, or other horizontal, top-down modes, block-level elements are organized vertically.
Internal connection elements behave differently - they don’t start on another line; they are arranged on the same line as other internal connection elements, adjacent text content (or wrapped) as long as there is enough space within the width of their parent block-level element. If there is not enough space, overflowing text or elements will move to a new line.
If two adjacent elements have margins set and the two margins overlap, the larger setting is preserved and the smaller one disappears - this is called margin overlay, and we’ve seen it before.
What is BFC?
Block Formatting Context (BFC) is part of the visual CSS rendering of a web page, the area where the layout process of block-level boxes takes place, and the area where floating elements interact with other elements.
The following methods will create a block formatting context:
- root element (< html >)
- Floating element (float value is not none)
Absolutely positioned elements (position value is absolute or fixed) - Inline block element (display value is inline-block)
- Table cells (display value is table-cell, default value for HTML table cells)
- Table title (display value is table-caption, default value for HTML table title)
- Anonymous table cell elements (display values are table, table-row, table-row-group, table-header-group, table-footer-group (default values for HTML table, tr, tbody, thead, tfoot, respectively) or inline-table)
- block element with overflow value not visible, clip
- display elements with flow-root value
Elements containing values of layout, content or paint
Elastic elements (immediate children of a flex or inline-flex element with a display value) if they are not themselves flex, grid, or table containers
Grid elements (immediate children of a display value grid or inline-grid element) if they are not themselves flex, grid, or table containers - Multi-column containers (column-count or column-width (en-US) values are not auto, including column-count is 1)
An element with a column-span value of all always creates a new BFC, even if the element is not wrapped in a multi-column container (specification changes, Chrome bugs)
The formatting context affects the layout. Usually, instead of changing the layout, we will create a new BFC for positioning and clearing floats, because it will:
- Includes internal float
- Exclude external float
- Block, margins overlap
Contains internal float
Make the floating content equal to the surrounding content. That is, the display of the inner floating element will not exceed the BFC.
To better understand BFC, let’s take a look at the following.
In the example below, we float the < div > element and give it a border effect. The content in < div > is now floating around the floating element. Since the floating element is taller than the element next to it, the border of < div > is pierced through the float. As we explained in In Flow and Out of Flow, floats are separated from the doc flow, so the background and border of < div > only contain the content, not the float.
Use’overflow: auto ’
When creating a BFC containing floating elements, it is common practice to set the parent element to overflow: auto or other values other than the default overflow: visible. ‘< div >’ elements become mini-layouts in layouts, and any child elements are included.
Use overflow to create a new BFC because the overflow attribute tells the browser how to handle overflow content. If you use it just to create a BFC, you may encounter unwanted scrollbars or shadows, which need to be noted. Also, for subsequent developers, it may not be clear why overflow was used at the time, so it’s best to add some comments to explain why.
Use’display: flow-root’
The value of a new display property that can create a BFC without side effects. Use’display: flow-root 'in the parent block to create a new BFC.
After setting the display: flow-root attribute to the < div > element, all content in the < div > element will participate in BFC, and floating content will not overflow from the bottom.
As you can see from the name of the flow-root value, it creates a new context for streaming layout, similar to the browser root (html) element.
1 | <section> |
1 | section { |
Exclude external float
In the following example, we use display: flow-root and float to implement a two-column layout, because the BFC established in the normal doc flow must not overlap the outer margins of any float in the block formatting context where the element itself is located.
1 | <section> |
1 | section { |
Avoid overlapping margins
The top and bottom margins of a block are sometimes combined (folded) into a single margin that is the maximum of the single margin (or only one of them if they are equal), a behavior called margin folding.
There are three situations where margins overlap:
Between adjacent elements in the same layer
The margins overlap between two adjacent elements, unless the latter element plus clear-fix clears the float.
No content separates parent elements from descendant elements
The parent block element and its inner descendant block appear if there is no border, padding, inline content, or creating a block-level formatting context or clearing floats to separate the upper boundary margin-top of a block-level element from the upper boundary margin-top of one or more descendant block-level elements within it; or no border, inline margin, inline content, height, minimum height min-height or max-height to separate the lower boundary margin-bottom of a block-level element from the lower boundary margin-bottom of one or more descendant block elements within it The outer element boundary overlaps, and the overlapping part will eventually overflow outside the parent block element.
Empty block-level element
Boundary folding also occurs when the boundary margin-top on a block element is directly attached to the boundary margin-bottom under the element. This happens when a block element has no border, padding, height, minimum height min-height, maximum height max-height, content set to inline or clear-fix at all.
Box model
There are two types of “boxes” that we use extensively in CSS - block boxes and internal connection boxes. These two types of boxes exhibit different behaviors in terms of page flow and the relationships between elements:
A box defined as a block exhibits the following behavior:
- The box expands in the inline direction and takes up all the free space of the parent container in that direction, meaning in most cases the box will be as wide as the parent container
- Every box wraps
- width and height properties can come into play
- Padding, margin and border will “push” other elements from around the current box
If a box is displayed as inline, its behavior is as follows:
- The box does not generate a line break.
- The width and height properties will not work.
Vertical padding, margins, and borders are applied but do not push other inlined boxes away. - Horizontal padding, margins, and borders are applied and push other inlined boxes away.
It’s best to also explain the interior here
Similarly, the box model has an internal display type, which determines how the elements inside the box are laid out. By default, it is in accordance with
However, we can use similar
What is CSS Box?
The full CSS box model applies to block-level boxes, with internal connection boxes using only the parts defined in the box model. The model defines each part of the box - margin, border, padding, and content - which together create the content we see on the page. To add some extra complexity, there is a standard and alternative (IE) box model.
Parts of the box model
To form a block-level box in CSS, you need:
Content box: This area is used to display content, and the size can be set by setting width and height.
Padding box: A blank area enclosed outside the content area; the size is set by the padding related properties.
Border box: Border box package content and padding. The size is set by border related properties.
Margin box: This is the outermost area, the empty space between the box and other elements. The size is set by the margin-related property.
Standard box model
In the standard model, if you set the width and height of the box, you actually set the content box. The padding and border plus the set width and height together determine the size of the entire box. See the image below.
Assuming width, height, margin, border, and padding are defined:
1 | .box { |
If using the standard model width = 410px (350 + 25 + 25 + 5 + 5), height = 210px (150 + 25 + 25 + 5 + 5), padding plus border plus content box.
Alternative box model
You might think that adding borders and padding to the size of the box is troublesome, and you’re right! For this reason, css has an alternative box model. Using this model, all widths are visible widths, so the content width is that width minus the border and padding. Use the same style as above to get (width = 350px, height = 150px).
The default browser will use the standard model. If you need to use an alternative model, you can do so by setting box-sizing: border-box for it. This will tell the browser to use border-box to define the area, thus setting the size you want.
If you want all elements to use the alternative mode, and it’s really common, set box-sizing on the < html > element, and then set all elements to inherit that property, as in the example below. For a deeper understanding, see the CSS Tricks article on box-sizing.
1 | html { |
Summary
In simple terms, the box model refers to how the width and height of this element are calculated, while BFC refers to the fact that its internal and external elements will not affect each other
Whether it is a box model can be set directly through css attributes, such as the display attribute, but whether it is BFC is not a css attribute, but in some cases, a context will be created.