Tutorial Categories:

HTML/CSS JavaScript/AJAX Server-Side Marketing General Comp-Sci

How User Agents Lay Out Documents Using CSS

By Justin Poirier

In an HTML or other XML document, each element that uses CSS has a "display" CSS property that determines whether it should be placed next to its sibling elements1 (value "inline") or on a separate line (value "block") 2. A user agent decides how to lay out a document by moving down through the tree of elements and attributes (the DOM tree) and dealing with the display properties of elements as it goes3. If a node in the tree has a mixture of both inline and block children, the user agent will split the children up into groups, first laying out the groups as if they were single entities, and then for each group layout out its elements as if the only siblings they had were each other. As the user agent traverses the DOM tree in this way, it in effect creates a second tree that's similar to the main tree, but contains at each node a construct declaring that all children nodes should be laid out together. This construct may represent an element or it may represent a grouping created by the user agent when it encountered both block and inline elements at the same level. This construct is called a box.

A box created for an inline element, or for a group of elements that the user agent placed together and decided should flow like an inline element, is called an inline box. A box created for a block element, or for a group of elements that the user agent placed together and decided should flow like a block element, is called a block box.

The user agent decides how to group elements into boxes to deal with mixed block and inline siblings in the following way: any series of consecutive inline elements are grouped into a single block box. As such they will appear inline to one another, but the group as a whole being a block box, will occupy its own line in the flow of the layout. In this way it can be seen that any box that initially contains mixed block and inline siblings is converted to only contain block children, and therefore in the end, no box in the document will contain both inline and block children.

The user agent also creates boxes when there is anonymous content, that is, a string of text appearing in the html that is not part of an opening or closing tag. For this text, an inline box is created.

Boxes created for groups of elements or for anonymous content are called anonymous boxes.

If all the inline boxes within a given parent box cannot fit on one line, they will be wrapped to the next line. The area making up each line is called a line box. A line box is not an actual box as we've defined it.

A box's parent box is called its containing block. Note that despite the name, a containing block is not necessarily a block box. It's obviously possible that a containing block is an inline box.

When the sibling boxes within a containing block, after any anonymous boxes are established, are block boxes, it is said that the containing block has a block formatting context. When the siblings are inline boxes, the containing block has an inline formatting context.

The process we've described for laying out the inline and block elements of a document is called the normal flow.

There are elements that are an exception to this process: floating elements, or floats. These elements have their "float" property set to either "left" or "right". Since a float is not part of the normal flow, it does not get placed in the tree of boxes that is created. However, the float's parent element will have been placed in this tree, and therefore will serve as a containing block for other boxes. The float will be placed on the far right or left portion of the screen space given to this containing block (based on whether the float property is set to "right" or "left"), and the boxes in the containing block will flow next to the float in their usual inline or block manner.

If the boxes in the containing block made by the float's parent are block boxes, the user agent will begin placing them on separate lines as usual, and only put the float in place when it comes to it in the order of the HTML code. The float will be placed on the next unused line, and subsequent boxes will flow next to the float.

Boxes that flow to the right or left of a float do not actually shift over or change size--only their paddings change so that the available space for their contents will shift/shrink. Therefore the line boxes used to place inline content within them may change. Due to this behaviour, changing the margin of an element flowing next to a float sets the minimum distance to the edge of the containing block (ie. to the far side of the float), and not to the float itself.

This entire process for laying out documents is called the visual formatting model, and was created by the W3C. The official definition of it is part of the Candidate Recommendation of CSS 2.1.

The CSS text-align property only applies to inline elements.

1 and all consecutive inline ancestor/descendent elements
2 There are actually more possible values than this, but they are beyond the scope of this document.
3 As we will see, float elements are not actually laid out this way.