Box Model

Loading...

Overview

The CSS box model represents the space occupied by an element and consists of four areas: margin, border, padding, and content region (width and height). The image below shows a block element with a 10px margin, 20px border, 30px padding and a width and height of 100px. The resulting box height and width is 220px by 220px.

Although most HTML elements have these properties, it's important to note that setting one doesn't always mean that it will render in the way shown above. For example, a margin edge can be collapsed, overlapped or transferred to another element. Many examples in this lab will show that setting the top-edge of a margin will sometimes cause it to be transferred to the top-edge of an ancestor.

This is a common theme in CSS. Setting a value will sometimes have only a partial effect or affect a different element altogether or have no affect at all (e.g., setting the opacity to 1 can have no affect but setting it to 0.6 can, but instead of appearing as 0.6 it may appear as 0.3 - see Irreversible Opacity).

Shared CSS

This section defines styles shared by all experiments on this page. Each class uses the default static position. Since position can't be inherited, the position remains static unless explicitly set. Also, there is no margin or padding used, except for extension classes (e.g., the "with-margin" class). These styles will often be applied to three nested divs: outermost, which contains middleGrid, which in turn contains innermost.

Outermost
MiddleGrid
Innermost

Basic Margin and Position

This section consists of basic experiments where setting the margin on an element affects only that element and not a different element (or both).

Absolute in Static

Innermost is given a 20px margin. Since it's an absolute-positioned div inside a static one, the results are as expected: There's a 20px margin all around, with no side-effects.

MiddleGrid was not given a margin, since it's a static div nested inside a static div. Adding a margin would trigger the Vertical Margin Transfer effect.

position, margin, padding, border ./img/outermost.png, ./img/middleGrid.png, ./img/innermost.png outermost_bm10, middleGrid_bm10, innermost_bm10

Static in Absolute

Innermost is given a 20px margin. Since it's a static-positioned div inside an absolute one, the results are as expected: There's a 20px margin all around, with no side-effects.

MiddleGrid has been given a 10px margin. Since it's an absolute div nested inside a static one, the results are also as expected: 10px margin all around, with no side-effects.

position, margin, padding, border ./img/outermost.png, ./img/middleGrid.png, ./img/innermost.png outermost_bm20, middleGrid_bm20, innermost_bm20

Absolute in Relative

Innermost is given a 20px margin. Since it's an absolute-positioned div inside a relative div, the results are the expected 20px margin all around, with no side-effects.

MiddleGrid was not given a margin. Since it's a relative div nested inside a static one, adding a margin would result in the Vertical Margin Transfer effect.

position, margin, padding, border ./img/outermost.png, ./img/middleGrid.png, ./img/innermost.png outermost_bm30, middleGrid_bm30, innermost_bm30

Relative in Absolute

Innermost is given a 20px margin. Since it's a relative-positioned div inside an absolute one, the results are as expected: 20px margin all around, with no side-effects.

MiddleGrid was given a 10px margin. Since it's an absolute div nested inside a static one, the results are also as expected: 10px margin all around, with no side-effects.

position, margin, padding, border ./img/outermost.png, ./img/middleGrid.png, ./img/innermost.png outermost_bm40, middleGrid_bm40, innermost_bm40

Absolute in Absolute

Innermost is given a 20px margin. Since it's an absolute-positioned div inside an absolute div, the results are the expected 20px margin all around, with no side-effects.

MiddleGrid was given a 10px margin. Since it's an absolute div nested inside a static one, the results are also as expected: 10px margin all around, with no side-effects.

position, margin, padding, border ./img/outermost.png, ./img/middleGrid.png, ./img/innermost.png outermost_bm50, middleGrid_bm50, innermost_bm50

Margin Caveats

The margin of a block-level element can collapse, overlap or be transferred to another element, depending on a variety of circumstances. This section experiments with some of these effects.

Vertical Margin Transfer (VMT)

When a static or relative-positioned block-level element is nested inside of a static or relative-positioned parent, its top and bottom margins may be transferred up the hierarchy until a suitable ancestor is found. This is true for blocks of static elements nested in static elements, relative nested in static, static nested in relative and relative nested in relative.

For example, the experiment below uses a relatively positioned innermost div with a 20px margin, nested inside of a single statically positioned ancestor div. As expected, this pushes the innermost div 20px to the right, relative to its parent, outermost div.

Surprisingly, the top and bottom margins have no effect on the innermost div's distance from the top of outermost. Instead, the top and bottom margins bypasses the innermost div and are directly transferred to the top of the outermost div, pushing it down by 20px (as evidenced by the more than 20px gap above outermost) as well as pushing the display wrapper down at the bottom.

position, margin, padding, border ./img/middleGrid.png, ./img/innermost.png outermost_mc00, innermost_mc00

Top Margin Transfer

This experiment highlights the affect of Vertical Margin Transfer on the top margin (using the same div structure as most of the other examples on this page). The bottom margin is not affected in this scenario, because the content height of the ancestor divs are explicitly set.

As can be seen in the Rendered Result, the 20px margin defined by the with-margin class and provided to the innermost div, has been transferred to the top of the outermost div (as evidenced by the more than 20px gap above outermost).

position, margin, padding, border ./img/outermost.png, ./img/middleGrid.png, ./img/innermost.png outermost_mc10, middleGrid_mc10, innermost_mc10

Content Workaround for VMT

Adding some content to the middle div can block the affects of Vertical Margin Transfer, when using static or relative divs. The top margin of the innermost div is now applied to the innermost div instead of outermost. position, margin, padding, border ./img/outermost.png, ./img/middleGrid.png, ./img/innermost.png outermost_mc20, middleGrid_mc20, innermost_mc20

Padding Workaround for VMT

Adding some padding to the outermost div can also mitigate the affects of Vertical Margin Transfer, but requires a lot of finagling of the outer and inner divs and is off by 1px. position, margin, padding, border ./img/outermost.png, ./img/middleGrid.png, ./img/innermost.png outermost_mc30, middleGrid_mc30, innermost_mc30

Border Workaround for VMT

Vertical Margin Transfer can be circumvented by adding a border to the outermost (or middle) div. The example below shows that by adding a border to outermost, the margin transfer from innermost is blocked. Instead, the top margin is now transferred to the middle div. Alternatively, adding a border to the middle div blocks the margin transfer to both middle and outermost divs all at once (i.e., adding a border or padding to an outer div blocks the propagation of the margin transfer feature). position, margin, padding, border ./img/outermost.png, ./img/middleGrid.png, ./img/innermost.png outermost_mc40, middleGrid_mc40, innermost_mc40

Border

TODO

Padding

TODO

Vertical Centering

The multi-line text in innermost can be easily centered by using the table-cell technique described by lluisaznar here. position, margin, padding, display, border ./img/outermost.png, ./img/middleGrid.png, ./img/innermost.png, ./img/contentRegion.png outermost_vc00, middleGrid_vc00, innermost_vc00, centerText_vc00

Multiple Inner Boxes

This series of experiments shows how multiple inner boxes behave in the box model.

Multiple Absolute Inner Boxes

This experiment uses two absolute positioned innermost boxes. Since position is absolute, they don't flow around each other. Instead, they stack on top of each other (unless positioned manually, as in this example). position, margin, padding, border ./img/outermost.png, ./img/middleGrid.png, ./img/innermost.png, ./img/innermost.png outermost_mib00, middleGrid_mib00, innermost_mib00, innermost_mib01

Multiple Static Inner Boxes

This experiment is the same as above, except now the innermost boxes are static (static boxes nested inside of an absolute box). Note: If the innermost boxes were relative positioned, the results would be the same.

The following behaviours of the innermost boxes can be observed:

Static boxes flow and stretch. position, margin, padding, border ./img/outermost.png, ./img/middleGrid.png, ./img/innermost.png, ./img/innermost.png, ./img/innermost.png, ./img/innermost.png, ./img/innermost.png outermost_mib10, middleGrid_mib10, innermost_mib10, innermost_mib11, innermost_mib12, innermost_mib13, innermost_mib14