The CSS visual formatting model is an algorithm that processes a document and displays it on visual media. This model is a basic concept of CSS.
The visual formatting model transforms each element of the document and generates zero, one, or several boxes that conform to the CSS box model. The layout of each box is defined by:
The model renders a box, in relation to the edge of its containing block. Usually, a box establishes the containing block for its descendants. However, a box is not constrained by its containing block; when a box's layout goes outside the containing block, it is said to overflow.
Box generation is the part of the CSS visual formatting model that creates boxes from the document's elements. Generated boxes are of different types, which affect how the visual formatting is done. The type of the box generated depends on the value of the display
CSS property.
An element is said to be block-level when the calculated value of its display
CSS property is: block
, list-item
, or table
. A block-level element is visually formatted as a block (e.g., paragraph), intended to be vertically stacked.
Each block-level box participates in a block formatting context. Each block-level element generates at least one block-level box, called the principal block-level box. Some elements, like a list-item element, generating further boxes to handle bullets and other typographic elements introducing the list item, may generate more boxes. Most generate only the principal, block-level box.
The principal block-level box contains descendant-generated boxes and generated content. It is also the box involved in the positioning scheme.
A block-level box may also be a block container box. A block container box is a box that contains only other block-level boxes, or creates an inline formatting context, thus containing only inline boxes.
It is important to note that the notions of a block-level box and block container box are disjointed. The first, describes how the box behaves with its parents and sibling. The second, how it interacts with its descendants. Some block-level boxes, like tables, aren't block container boxes. Reciprocally, some block container boxes, like non-replaced inline blocks and non-replaced table cells, aren't block-level boxes.
Block-level boxes that also are block container boxes are called block boxes.
In some cases, the visual formatting algorithm needs to add supplementary boxes. Because CSS selectors cannot style or name these boxes, they are called anonymous boxes.
Because selectors do not work with anonymous boxes, they cannot be styled via a stylesheet. This means that all inheritable CSS properties have the inherit
value, and all non-inheritable CSS properties, have the initial
value.
Block containing boxes contain only inline-level boxes or only block-level boxes. But often the document contains a mix of both. In that case, anonymous block boxes are created around adjacent inline-level boxes.
If we take the following HTML code (with default styling applied to it, that is <div>
and <p>
elements have display:block
:
<div>Some inline text <p>followed by a paragraph</p> followed by more inline text.</div>
Two anonymous block boxes are created: one for the text before the paragraph (Some inline text
), and another for the text after it (followed by more inline text
). This builds the following block structure:
Leading to:
Some inline text followed by a paragraph followed by more inline text.
Unlike the <p>
element's box, Web developers cannot control the style of the two anonymous boxes. Inheritable properties take the value from the <div>
's property value, like color
to define the color of the text, and set the others to the initial
value. For example, they won't have a specific background-color
, it is always transparent, the initial
value for that property, and thus the background of the <div>
is visible. A specific background color can be applied to the <p>
box. Similarly, the two anonymous boxes always use the same color for their text.
Another case that leads to the creation of anonymous block boxes, is an inline box that contains one or several block boxes. In that case, the box containing the block box is split into two inline boxes: one before, and one after the block box. All the inline boxes before the block box are then enclosed in an anonymous block box, so are the inline boxes following the block box. Therefore, the block box becomes the sibling of the two anonymous block boxes containing the inline elements.
If there are several block boxes, without inline content in-between, the anonymous block boxes are created before, and after the set of boxes.
If we take the following HTML code, with <p>
have display:inline
and <span>
have display:block
:
<p>Some <em>inline</em> text <span>followed by a paragraph</span> followed by more inline text.</p>
Two anonymous block boxes are created, one for the text before the span Element (Some inline text
) and one for the text after it (followed by more inline text
), which gives the following block structure:
Which leads to:
Some inline text followed by a paragraph followed by more inline text.
An element is said to be inline-level when the calculated value of its display
CSS property is: inline
, inline-block
or inline-table
. Visually, it doesn't constitute blocks of contents, but is distributed in lines with other inline-level content. Typically, the content of a paragraph with different formatting, like emphasis or images, is made from inline-level elements.
This diagram uses outdated terminology; see note below. Besides that, it is incorrect because the yellow ellipse on the right side is per definition either identical to the one on the left side, or bigger than that (it could be a mathematical superset), because the spec says "Inline-level elements generate inline-level boxes, which are boxes that participate in an inline formatting context", see CSS 2.2, chapter 9.2.2
Inline-level elements generate inline-level boxes that are defined as boxes participating to an inline formatting context. Inline boxes are both inline-level boxes and boxes, whose contents participate in their container's inline formatting context. This is the case, for example, for all non-replaced boxes with display:inline
. Inline-level boxes, whose contents do not participate in an inline formatting context, are called atomic inline-level boxes. These boxes, generated by replaced inline-level elements or by elements with a calculated display
value of inline-block
or inline-table
, are never split into several boxes, as is possible with inline boxes.
<style> span { display:inline; /* default value*/ } </style> <div style="width:20em;"> The text in the span <span>can be split in several lines as it</span> is an inline box. </div>
which leads to:
The text in the span can be split into several lines as it is an inline box.<style> span { display:inline-block; } </style> <div style="width:20em;"> The text in the span <span>cannot be split in several lines as it</span> is an inline-block box. </div>
which leads to:
The text in the span cannot be split into several lines as it is an inline-block box.As for block boxes, there are a few cases where inline boxes are created automatically by the CSS engine. These inline boxes are also anonymous as they cannot be named by selectors; they inherit the value of all inheritable properties, setting it to initial
for all others.
The most common case where an anonymous inline box is created, is when some text is found as a direct child of a block box creating an inline formatting context. In that case, this text is included in the largest possible anonymous inline box. Also, space content, which would be removed by the behavior set in the white-space
CSS property, does not generate anonymous inline boxes because they would end empty.
Line boxes are generated by the inline formatting context to represent a line of text. Inside a block box, a line box extends from one border of the box to the other. When there are floats, the line box starts at the rightmost border of the left floats and ends at the leftmost border of the right floats.
These boxes are technical, and Web authors do not usually have to bother with them.
Run-in boxes, defined using display:run-in
, are boxes that are either block boxes or inline boxes, depending on the type of the following box. They can be used to create a title that runs inside its first paragraph when possible.
Besides the inline and block formatting contexts, CSS specifies several additional content models that may be applied to elements. These additional models, used to describe specific layouts, may define additional box types:
Once boxes are generated, the CSS engine needs to position them on the layout. To do that, it uses one of the following algorithms:
In the normal flow, boxes are laid out one after the other. In a block formatting context, they are laid out vertically; in an inline formatting context, they are laid out horizontally. The normal flow is triggered when the CSS position
is set to the value static
or relative
, and if the CSS float
is set to the value none
.
There are two sub-cases of the normal flow: static positioning and relative positioning:
static
of the position
property, the boxes are drawn at the exact position defined by the normal flow layout.relative
of the position
property, the boxes are drawn with an offset defined by the top
, bottom
, left
and right
CSS properties.In the float positioning scheme, specific boxes (called floating boxes or simply floats) are positioned at the beginning, or end of the current line. This leads to the property that text (and more generally anything within the normal flow) flows along the edge of the floating boxes, except if told differently by the clear
CSS property.
The float positioning scheme for a box is selected, by setting the float
CSS property on that box to a value different than none
and position
to static
or relative
. If float
is set to left
, the float is positioned at the beginning of the line box. If set to right
, the float is positioned at the end of the line box. In either case, the line box is shrunk to fit alongside the float.
In the absolute positioning scheme, boxes are entirely removed from the flow and don't interact with it at all. They are positioned relative to their containing block using the top
, bottom
, left
and right
CSS properties.
An element is absolutely positioned if the position
is set to absolute
or fixed
.
With a fixed positioned element, the containing block is the viewport. The position of the element is absolute within the viewport. Scrolling does not change the position of the element.
© 2005–2018 Mozilla Developer Network and individual contributors.
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.
https://developer.mozilla.org/en-US/docs/Web/CSS/Visual_formatting_model