CSS Positioning

To use CSS for layout effectively, it helps to know how it's used to position page content. This article gives an overview of the methods and rules that govern visual rendering in the CSS2 specification. It also points out some things to watch out for.

Although the specification applies to any device for displaying web pages, this article focuses on how it works in browsers. Many details are left out for the sake of simplicity. For a definitive reference, see the standards publication.

It's important to remember that a given browser may not support a given feature or may even implement it incorrectly. Also, there is some leeway provided within the standards where individual browsers are free to deal with situations as they please. Where appropriate these inconsistencies are noted.

The Box Model

To understand positioning in CSS you must first understand the box model. For display purposes, every element in a document is considered to be a rectangular box which has a content area surrounded by padding, a border and margins. The illustration below shows these various parts.

content content content content content content content content content content content content content content content content content content content content content content content content content content content content content content content content content content content content

margin border padding content

Margins are always transparent. Borders come in various styles. Background settings for an element apply to the the area just inside the borders which includes both the padding and content areas. For purposes of illustration however, the padding area is shown in a slightly darker color.

When referring to boxes throughout this article, the term "margin edge," "border edge", etc. means the the outer boundary of the corresponding box area as shown above.

Margins, borders and padding are all optional but for purposes of calculating positions and sizes they are given a default width of zero if not specified. Different widths can be set for each individual side (top, right, bottom and left) if desired. Margins can even have negative values.

The width and height of each box is equal to the width and height of the outer margin box. Note that this is not the necessarily the same as the width and height of the content area.

A box can contain any number of other boxes, creating a hierarchy of boxes that corresponds to the nesting of page elements. The browser window serves as the root element for this hierarchy.

Box Types

There are two basic types of boxes, block and inline. Block boxes are generated by elements such as P, DIV or TABLE. Inline boxes are generated by tags such as B, I or SPAN and actual content like text and images.

The box type may also be set using the display property. Setting a value of block on an inline element, for example, will cause it to be treated as a block element. Note that if you set the display to none, no box is created. The browser acts as if the element did not exist. Likewise, any nested elements are ignored as well, even if they specifically declare some other display value.

There are other types of boxes which apply to special elements like lists and tables. However, these are ultimately treated as block or inline boxes for positioning purposes. As such, these other box types not covered here.

Containing Blocks

Block boxes act as a containing block for any boxes within them. For example, in this code:

<div> This is the first sentence. <p>This is the second sentence.</p> </div>

the DIV element establishes a containing block for both the first string of text and the P element. The P element in turn creates a containing block for the second text string.

It's interesting to note that while the text of the first sentence in the above example generates an inline box, there is considered to be block box surrounding it. These "anonymous" block boxes are used to simplify the positioning process. The result is that a block box will only contain either all inline boxes or all block boxes, even if some of those block boxes only act as a wrapper for an inline box.

This containing block is used in determining both the position of the boxes within it and in some cases, the dimensions of those boxes. For example, if an element has a style setting of width:50%; its width will be set to half the width of its containing block.

For any element that is not absolutely positioned, the containing block is considered to be the content edge of its most recent, block-level ancestor. If none exists, the browser window serves as the containing block. Absolutely positioned elements are discussed separately.

Positioning Schemes

There are three positioning modes or schemes in CSS2: normal, float and absolute. Each has its own set of rules. Every box is positioned using one of these schemes but different boxes will use different schemes depending on their position and float style settings.

Normal Flow

Normal flow is the default scheme used for positioning. It applies to any element that does not specify position:absolute or fixed and is not floated.

In this scheme, block boxes flow vertically starting at the top of their containing block with each placed directly below the preceding one. Inline boxes flow horizontally from left to right.

You should note that vertical margins are collapsed in the normal flow. That is, instead of adding the bottom margin of a box to the top margin of the one immediately below it, only the larger of the two values is used, as illustrated here.

content content content content content content content content content

content content content content content content content content content content content content content content content content content content

Horizontal margins, however, are never collapsed.