CSS Key Concepts: Visual Formatting Model

w3cplus
24 min readJan 28, 2024

Most web developers know that there is a box model in CSS , but few people know that there is another model in the CSS world, and it is the CSS visual formatting model. CSS visual formatting model (English called Visual Formatting Model ), is the ninth part of the CSS 2.2 specification . This model is mainly used to deal with the calculation rules used when displaying documents on visual media. From this sentence alone, it is estimated that many colleagues will be confused. What the hell is a visual formatting model? You don’t have to rush to know what a visual formatting model is, just know that it is an important part of CSS. If you understand the knowledge points involved in this part, it will help you better understand and learn CSS, especially web layout.

What is a visual formatting model?

In the box model We learned that in the world of CSS, any element is a box, which has a technical term, namely the box model . The visual formatting model converts elements in the document into boxes according to the CSS box model. Seeing this, many colleagues may be more confused, “ Any element is a box, and the visual formatting model converts elements into boxes. Are all boxes the same? “?

The first thing to declare is that the visual formatting model and the CSS box model are not the same thing !

To put it simply, a Web page (document tree) is made up of boxes (because any element can be regarded as a box), while the visual formatting model is a set of rules for calculating the rules for transforming elements into boxes . The layout of the page is composed of the positions of these boxes. Then understand the rules of how elements are converted into boxes, and understand how the Web page is laid out. The layout of each box is mainly determined by the following factors:

  • Size of the box : precisely specified, specified by constraints, or not specified
  • Types of boxes : inline, inline-level, atomic inline-level, and block
  • Positioning scheme : normal flow positioning, floating positioning or absolute positioning
  • Other elements in the document tree : i.e. child or sibling elements of the current box
  • Window size and position
  • The size of the included images
  • Other external factors

Let’s take a look at a diagram first, which is constructed from the following HTML structure:

<body>
<header>
<nav></nav>
</header>
<article>
<p></p>
<figure></figure>
<p></p>
</article>
<aside></aside>
<footer></footer>
</body>

Each element is a box, and the box can contain one or more boxes. Also as shown in the figure above, the visual formatting model of CSS renders the box according to the boundaries of the box’s containing block (i.e. a block containing other boxes ). Usually, the box creates an containing block containing its descendant elements, but the box is not limited by the containing block. The layout of the box will burst the containing block (i.e. run out of the containing block boundary). This phenomenon is often referred to as overflow in CSS.

Note that overflow is another important concept in CSS. If you don’t know much about it, Please pay attention to my column , which will be introduced later. In addition, I would like to remind everyone that overflow often has some problems. If you want to learn more about overflow-related problems and how to troubleshoot them. Everyone recommends that you read “ Overflow FAQs and Troubleshooting “ in “ Defensive CSS Intensive “!

Overflow is a very interesting feature that is often encountered in web layouts, but it is not covered in this chapter.

Returning to the previous question, is the box in the visual formatting model the same box as the box in the CSS model?

The box is the same box, but the two models do different things. The CSS box model is used to calculate the box size ( width , height , padding , border and margin ); the visual formatting model is used to calculate the box position (determined by the seven factors mentioned earlier) !

Brief Introduction to Terms

The following content will cover a lot of terms related to CSS theory, and these terms can be difficult to understand. It may not be well understood at the moment, but it doesn’t matter, as you learn more about CSS, these terms will become clearer and clearer. So far, you just need to know these terms and their concepts.

block

Block, an abstract concept in which a block occupies a separate area on the document flow and is stacked vertically (by default).

contain block

A containing block refers to a block that contains other boxes.

The position and size of an element’s box(es) are sometimes calculated relative to a certain rectangle, called the containing block of the element.

Large means that the positioning and size of the box are calculated with reference to the edge of a rectangle, which is the container block of an element. The container block of an element is roughly defined as follows:

  • The root element is an initial container block.
  • Second, if an element’s position is relative or static , its container block is generated by its nearest block container parent or by a parent element that creates a formatting context
  • If an element has position: fixed set, its container block is typically generated by the window
  • If the element has position: absolute set, its container block is generated by the nearest parent element with the position value set to relative , absolute or fixed , or by the root element if none of the parents are set
  • An element with a non- none value of the transform attribute generates a container block whose fixed children are positioned

So how to judge the containing block? We use a diagram of w3chelp to show you:

box

Box, an abstract concept created by the CSS engine based on the content in the document, is mainly used for the positioning, layout, and formatting of document elements. Boxes and elements are not one-to-one correspondence, sometimes multiple elements will merge into a box, and sometimes an element will generate multiple boxes (such as anonymous boxes).

As we all know, an HTML document generates a DOM tree.

Similarly, CSS also builds a box tree based on the document structure:

More people may be more receptive to the concept of CSSOM. Here’s a side note that it is the DOM tree and the CSSOM tree that make up a rendering tree:

In fact, this involves the principle of browser rendering. Similar to the following image, the layout is only part of the whole process:

Going a bit further, let’s get back to the topic. If you are interested in this knowledge, you can check out some topics related to browser rendering or CSS engines.

Block-level boxes and in-line boxes

Block-level boxes are generated by block-level elements. A block-level element generates at least one block-level box, but it is also possible to generate multiple (e.g. list item elements).

Inline-level boxes are generated by inline elements. Similarly, an inline element will generate at least one inline box. Inline boxes include two types: inline boxes and atomic inline boxes, the difference being whether the box participates in the creation of inline formatting context.

Simply put, block elements generate block group boxes, and inline elements or inline-level elements generate inline-level boxes. The two types of boxes can be switched through display .

Block box and inline box

Block Box, if a block-level box is also a block container box, it is called a block box. In addition to named block boxes, there is another type of block box that is anonymous, called Anonymous Block Box, which cannot be selected by CSS selectors.

Inline boxes are generated by non-replaced elements and belong to a type of inline box. Except for inline boxes, all other inline boxes are atomic inline-level boxes. Its typical feature is that as a whole, it cannot be split into newlines. Similarly, inline boxes also have anonymous inline boxes. For direct text without any element wrapping, the CSS engine will create anonymous inline boxes for it.

Simply put, inline boxes that participate in inline formatting context creation are called inline boxes.

Atomic inline box

Atomic Inline-level Box is an inline-level box that does not participate in inline formatting context creation. The atomic inline-level box was originally called Atomic Inline Box and was later modified. The contents of the atomic inline-level box will not be split into multiple lines for display.

Line box

Line boxes and inline boxes are different. Line boxes are boxes generated by inline formatting context to represent a line. Line boxes are formatted from one side of the containing block to the other. Generally, browsers create an invisible line box for each line.

The internal structure of the line box is also quite complex, and it is also a complex and difficult-to-understand part of CSS. The following figure shows the construction of a line box.

Block container box

Block Container Box or Block Containning Box focuses on the current box as a container role. It does not participate in the layout and positioning of the current block, and only describes the relationship between the current box and its descendants. In other words, the block container box is mainly used to determine one of its child elements, layout, etc.

Block-level elements and inline-level elements

CSS boxes are very complex, there are block boxes and block boxes ( inline boxes and inline boxes ). Various boxes make beginners headache. However, elements are much simpler than boxes, which only have block-level elements and inline-level elements .

Block-level Element refers to an element whose display value is block , list-item , table , flex , and grid , etc. The element will become a block-level element. Whether an element is a block-level element is only an attribute of the element itself and is not directly used for formatting context creation or layout.

Inline-level Element refers to an element whose display value is inline , inline-block , inline-table , inline-flex and inline-grid , etc., which will become an inline-level element. Like block elements, whether an element is an inline-level element is only an attribute of the element itself and is not directly used for formatting context creation or layout.

Window (Viewport)

Simply put, a window is the visible area in a browser. The window size refers to the size of the browser’s visible area.

Today, facing different end point screens, the window size also varies.

Especially on mobile devices, windows are divided into three categories: Layout viewport , Visual viewport and Ideal viewport :

The Ideal viewport is the most suitable viewport for mobile devices. The width of the Ideal viewport is equal to the screen width of the mobile device. As long as the width of an element is set to the width of the Ideal viewport in CSS (in px ), then the width of this element is the width of the device screen, which is the effect of a width of 100% . The significance of the Ideal viewport is that there is no fixed size for the Ideal viewport, and different devices have different Ideal viewports. No matter what resolution the screen is, websites designed for the Ideal viewport can be perfectly presented to users without manual scaling or horizontal scroll bars.

Format context

By default, boxes are stacked from left to right, top to bottom, according to their position in HTML :

As can be seen from the figure, the boxes of some elements are rendered as a complete line, such as h1 , li and other elements; the boxes of some elements are rendered as horizontally arranged until the line is full and then wrapped, such as em , strong and other elements.

This is because different boxes use different formatting contexts for layout. Each formatting context has its own different rendering rules, which are used to determine how its child elements are positioned and their relationship with other elements. It’s like pouring water into different containers, which will have different shapes.

There are many types of formatting contexts in CSS, such as IFC (Inline Formatting Context) , BFC (Block Formatting Context) , FFC (Flexbox Formatting Context) and GFC (Grid Formatting Contexgt) . The collection of these formatting contexts can be called visual formatting models .

Formatting context is a very important part of CSS, and I will spend some time explaining *FC in CSS later.

Generation of the box

Box generation is part of the CSS visual formatting model used to generate boxes from document elements. There are different types of boxes, and different types of boxes have different formatting methods. Different boxes also affect the behavior of elements or their descendants. In CSS, the display property is usually used to clarify the type of box.

The value of the CSS display property will cause elements in the document to generate a Principal Box to contain descendant boxes and content, and it is also a box participating in the positioning scheme. Some elements may generate additional boxes in addition to the main box. For example, setting the display value to the list-item element. The placement of these additional boxes is related to the main box.

When CSS display switches between different values, different boxes will be generated; at the same time, when the Client renders the HTML document, it will come with a box for each element.

Everything is a box

In CSS, everything generates boxes. Web pages are essentially a set of block-level boxes and internal connection-level boxes. You can understand these boxes well by selecting elements on the page in the browser’s developer tools. You can see the boxes that make up the layout and the various properties of the boxes ( margin , padding , border , and content , etc.), and you can also see how these box properties are applied:

Control box generation

As mentioned earlier, everything in CSS is a box, and the types between boxes can be switched using different values of display . There are also two different values in display , none and contents , which can be used to control whether the box should be explicitly . If you want elements in HTML not to generate boxes in CSS, you need to suppress box generation in some way. You may want to do two things:

  • Prevent elements and their descendants from generating a box
  • Prevent the element itself from generating a box, but its descendant elements will still generate a box

The display properties none and contents in CSS help us do both:

  • If the display value of an element is none , neither the element nor its descendant elements will be visible and no boxes will be generated
  • If the display value of an element is contents , the box properties of the element itself ( margin , padding , border , etc.) will be lost, but its descendant elements will not be affected. That is, the element itself is no longer a box, but its descendant elements are still a box

That is, the CSS display property controls box generation:

  • When the display value of the element is not none or contents , the element can generate a box, and the type of the box is determined by the type of its value
  • When the display value of an element is none , neither the element nor its descendant elements generate boxes
  • When the display value of an element is contents , the element itself does not generate a box, but its descendant elements will still generate the corresponding box according to the display

Next, let’s take a look at the generation of various boxes.

Block-level elements and block boxes

When the display of an element is block , list-item , table , flex or grid , the element becomes a block-level element. A block-level element is formatted as a block, such as the familiar div , p , li and other elements. These block-level elements are stacked from left to right and top to bottom by default.

Each block-level box will participate in the creation of the Block Formatting Context (commonly known as BFC ), and each block-level element will generate at least one block-level box, which is the Principal Block-level Box. Some elements will generate additional boxes in addition to the Principal Block-level Box. For example, an element with a display value of list-item will generate a Marker tag box (Marker tag refers to markers similar to bullet points) in addition to generating the Principal Block-level Box, while elements that generate list items may generate more boxes.

Most elements generate only one main block-level box.

The main block-level box contains boxes and content generated by descendant elements, and also participates in positioning schemes. A block-level box may also be a block container box. A block container box (Block Container Box) either contains only other block-level boxes or only contains inline boxes and creates an inline formatting context (Inline Formatting Context, commonly known as IFC ).

Note that block-level boxes are different from block container boxes , this is important. Block-level boxes describe the behavior between elements and their parent and sibling elements; block container boxes describe the behavior between elements and their descendants. These block-level boxes are not block container boxes, such as table ; and some block container boxes are not block-level boxes, such as non-replacement inline blocks and non-replacement table cells.

If a box is both a block container box and a block-level box at the same time, the box is called a block box (Block Box) .

Earlier we mentioned various terms such as blocks, boxes, and elements. So here we briefly understand the relationship between blocks (Block) , containing blocks (Containing Block) , boxes (Box) , block-level boxes (Block-level Box) , block boxes (Block Box) , block container boxes (Block Containning Box) and block-level elements (Block-level Element) :

  • When the display value of the element is block , list-item , table , flex and grid , the element will generate a block-level element
  • The block-level element generates a block-level box.
  • The block-level box participates in the block formatting context (BFC) creation
  • Block-level Elements describe the behavior between elements and their parent and sibling elements
  • A block container box (Block Containning Box) Describes the behavior between an element and its descendants. It either contains only a block-level box (Block-level Box) , or only contains an inline-level box (Inline-level Box) . Some block container boxes are not block-level boxes , and block-level boxes are sometimes not block container boxes
  • A box that is both a block-level box and a block container box is called a block box.
  • In addition to this, there is also the Anonymous Block Box (Anonymous Block Box) (introduced later)

For example, an example like the following:

Inline elements and inline boxes

CSS display has many attribute values. When the value of the display attribute of an element is inline , inline-block , inline-table , inline-flex or inline-grid , the element is called an inline-level element. When displayed, it does not generate content blocks, but can be displayed on multiple lines with other inline-level content. For example, paragraph p containing multiple formatted content (such as strong , img <--atag--20/>, etc.) can be composed of inline-level elements.

Inline-level elements generate inline boxes that participate in the creation of the inline formatting context. Inline boxes are both inline boxes and boxes whose contents participate in the creation of the inline formatting context of their container, such as all non-replacement boxes with the display: inline style. If the content of an inline box does not participate in the creation of the following inline formatting context, it is called an atomic inline box. Boxes created by replacing inline elements or elements with display values of inline-block , inline-table , inline-flex , or inline-grid cannot be split into multiple boxes like inline boxes.

Briefly summarize:

  • When the value of the element display is inline , inline-block , inline-table , inline-flex or inline-grid , the element is an inline-level element
  • Inline-level elements will generate inline-level boxes and participate in the creation of IFC
  • Similarly, an anonymous inline box will be created

Anonymous box

Anonymous boxes are divided into block anonymous boxes and inline anonymous boxes . In some cases, visual formatting requires adding some supplementary boxes that cannot be selected by CSS selectors, and these boxes are called anonymous boxes (Anonymous Box) .

CSS selectors cannot be applied to anonymous boxes, so styles cannot be set. That is, all inheritable CSS property values are inherited , and all non-inheritable CSS property values are initial .

For example, in the following example, the div element contains a p element, and there is a text before and after the p element:

<div>
我是直接文本
<p>我是块级元素,但是我的前后都不是</p>
我也是直接文本
</div>

In this example, the text content in the div element (the text content before and after the p element) creates an anonymous block box, which renders as follows:

In the above picture, the anonymous block box is located in the red box.

Another situation where anonymous block boxes are created is when an inline box contains one or more block boxes. At this time, the box containing the block box will be split into two inline boxes, located in front and behind the block box. All inline boxes in front of the block box will be wrapped in an anonymous block box, as will the inline boxes behind the block box. Therefore, the block box will become the sibling box of these two anonymous block boxes.

If there are multiple block boxes with no inline elements in between, two anonymous block boxes will be created before and after these boxes.

For example, an example like the following:

<p>Some <em>inline</em> text <span>followed by a paragraph</span> followed by more inline text.</p>

The p element is set to display: inline , and the display of the span is block . Two anonymous block boxes are also created: one is the text before the span element, and the other is the text after it.

Similar to block boxes, CSS engines sometimes automatically create inline anonymous boxes. It is common for the CSS engine to automatically create an inline formatting context for the text directly contained in the block box. In this case, the text will be contained in a large enough anonymous inline box. However, if only spaces are included, anonymous inline boxes may not be generated because spaces may be removed due to the setting of white-space , resulting in the final actual content being empty.

For example, the following example:

<p><span>Hellow</span> W3cplus.com!</p>

There are no block-level elements in the < p > element, nor are there elements that explicitly set displa to block , table , flex or grid , and directly contain text content, such as the " W3cplus.com " text in the above example. It belongs to the direct text of the p element. At this time, the CSS engine will create an anonymous inline box for it.

Other types of boxes

In addition to the boxes mentioned above, several content models are also defined in CSS, which can also be applied to elements. These models are generally used to describe layouts and may define some additional box types.

  • Table content model : may create a table wrapper box and a table box, as well as multiple other boxes such as table header boxes
  • Multi-column content model : Multiple column boxes may be created between container boxes and content
  • Flexbox content model : may create a flexbox
  • Grid content model : may create a grid box

Format context

There are many types of formatting contexts in CSS, in addition to the familiar BFC and IFC, there are also FFC created by Flexbox layout and Grid layout creating GFC, etc. These are collectively referred to as CSS formatting contexts, also known as the visual formatting model . The CSS visual formatting model is a mechanism used to process documents and display them on visual media. Simply put, it is used to control the position of the box, that is, to implement the layout of the page .

Formatting context can also be said to be a part of CSS visual rendering. Its main role is to determine the layout of the box model, how its child elements will be positioned, and the relationship and interaction with other elements Understanding CSS formatting context helps us master the key to various CSS layouts.

Inline formatting context

Inline Formatting Context (Inline Formatting Context), abbreviated as IFC . Mainly used to rule the formatting rules of inline-level boxes.

The height of the IFC line box is calculated based on the actual height of the highest containing inline elements. This mainly involves CSS properties such as font-size , line-height , vertical-align and text-align .

Inline elements are arranged horizontally from the top of the containing block, and margin , border , and padding take effect horizontally. Inline elements can be aligned vertically according to top, bottom, or base line.

When several inline elements cannot be placed horizontally in a single line box, they are assigned to two or more vertically stacked line boxes. Therefore, a paragraph is a vertical stack of many line boxes. These line boxes are not separated vertically (unless otherwise specified), and they do not overlap.

  • Vertically, when the height of an inline element is lower than the line box, the vertical-align property determines the vertical alignment.
  • Horizontally, when the total width of inline elements is smaller than the line box, the horizontal division of inline elements is determined by text-align .
  • In the horizontal direction, when the total width of inline elements exceeds the line box, inline elements will be assigned to multiple line boxes. If properties such as non-breakable lines are set, inline elements will overflow the line box.
  • Both sides of the line box touch the containing block, and the float element is placed between the line box and the containing edge.

The following rules will create an inline formatting context:

  • IFC is generated only if a block-level element contains only inline-level elements
  • The internal boxes will be placed one after another in uneven directions
  • The starting point of these boxes in the vertical direction starts from the top of the box containing the block
  • When placing these boxes, the space occupied by their horizontal padding , border and margin will be taken into account
  • In the vertical direction, these boxes may be aligned in different forms ( vertical-align )
  • All boxes on a line can be completely contained in a line box, and the width of the line box is determined by the containing block and the existing float
  • Row boxes in IFC generally have their left and right edges close to their containing blocks, but they may change due to the presence of floating elements. Floating elements are located between IFC and the row box, shortening the width of the row box
  • When the total width of the inline level boxes is less than the line boxes containing them, their horizontal rendering rules are determined by text-align
  • When the inline box exceeds the width of the inline box, it will be divided into multiple boxes, which are distributed in multiple inline boxes. If an inline box cannot be divided, it will overflow

IFC is mainly used for:

  • Inline elements follow text-align centered text
  • Inline elements stretch the height of the parent element, vertically centered by the vertical-align attribute

Block formatting context

Block Formatting Context (BFC) is part of the visual CSS rendering of a web page. It is the area where the layout process of block boxes occurs and where floating elements interact with other elements.

BFC is actually a rendering area in the page, which is isolated from other areas. Face elements in the container will not affect the outside, and external elements will not affect the child elements in the container.

The boxes inside the BFC are arranged in order from top to bottom. The distance between the boxes in the vertical direction of the BFC is based on the margin attribute, and the upper and lower margins will be superimposed. The left-most boundary of each element contacts the left side of the containing block BFC (for left-to-right formatting, otherwise the opposite). This is true even if there is a float. The area of the BFC is not folded with the box of the floating element. The height of the BFC is also affected by the floating element, which participates in the calculation.

The following rules can create a BFC:

  • Root element or element containing root element
  • Floating element (the element’s float is not none )
  • Absolute positioning element (element’s position is absolute or fixed )
  • Inline block element (element’s display is inline-block )
  • Table cell (the display of the element is table-cell , which is the default value for HTML table cells)
  • Table title (the display of the element is table-caption , and the HTML table title defaults to this value)
  • Anonymous table cell element (the element’s display is table , table-row , table-row-group , table-header-group , table-footer-group (the default attributes of HTML table , row , tbody , thead , tfoot ) or inline-table )
  • overflow value not visible block element
  • display elements with flow-root value
  • contain elements with layout , content or strict values
  • Elastic element ( display is a direct child of a flex or inline-flex element)
  • Grid element ( displayed as a direct child of a grid or inline-grid element)
  • Multi-column container (elements with column-count or column-width not auto , including column-count of 1 )
  • Elements with column-span of all always create a new BFC, even if the element is not wrapped in a multi-column container

The block formatting context contains all the content inside the element that created it. Its main use is:

  • Create an independent rendering environment
  • Prevent height collapse caused by floating
  • Prevent adjacent outer margins from folding

Flex formatting context

Flexbox Formatting Context, commonly known as FFC . When the display value is flex or inline-flex , a Flexbox container is created. The container creates a new formatting context for its content, the Flex formatting context .

However, it should be noted that Flexbox containers are not block containers (block-level boxes), and the following properties that apply to block layouts do not apply to Flexbox layouts:

  • The column-* attribute in multiple columns does not apply to Flexbox containers
  • The float and clear properties will not work on Flex projects and will not take Flex projects out of the document flow
  • The vertical-algin property will not work on Flex projects
  • ::first-line and :: first-letter pseudo-elements do not work with Flexbox containers, and Flexbox containers do not provide their ancestors with the first formatted line or first letter

Grid formatting context

Grid Formaatting Context, commonly known as GFC . Similar to FFC, when the display value of an element is grid or inline-grid , a Grid container will be created. The completer creates a new formatting context for its content, the Grid formatting context . This is the same as creating a BFC, except that a grid layout is used instead of a block layout.

The grid container is not a block container, so some properties that are assumed to be designed for block layout do not apply in the context of grid formatting. In particular:

  • float and clear will not work on grid items. However, the float property still affects the calculated value of display on grid completer child elements, as this occurs before the grid item is determined
  • vertical-align will also not work on grid projects
  • ::first-line and :: first-letter pseudo-elements do not work with grid containers, and grid containers do not provide them with the first formatting line or the first formatting letter

Summary

This chapter discusses various terms in CSS, especially various boxes, which can be confusing and even painful. Hopefully, this article’s explanation of these terms can help reduce some of the pain. In addition, in addition to introducing various terms in CSS, the article also explains the formatting model of CSS. Beginners may not take this concept seriously, but in fact, if you don’t understand the CSS formatting model clearly, you will encounter many headaches with CSS layout, and even cannot quickly solve layout problems.

If you have carefully read the above content, you may know that the CSS visual formatting model is a collection of various formatting contexts. Different formatting contexts determine the type and layout of each box. Although both the CSS visual formatting model and the CSS box model are used to handle boxes, there are essential differences between them.

  • The CSS box model is used to calculate the size of the box
  • The CSS formatting model is used to determine the type of box and to calculate the position of the box

--

--

w3cplus

Author of "Modern CSS," "Modern Web Layout," "In-Depth CSS Defense," and "A Journey into Web Animation!"