The Box Model

Every HTML element, occupies a rectangular space (or box) in a web page.  This behavior is define by the CSS box model.  By default these rectangular boxes, can be nested, vertically stacked, horizontally adjacent, and as we’ll see later, layered over one another.

Take for example, the code below.

<div style="background-color: purple; color: white;">
    Purple
    <p style="background-color: blue;">Blue <span style="background-color: red;">Red</span></p>
    <p style="background-color: green;">Green <span style="background-color: orange;">Orange</span></p>
    Purple
</div>

This results in the following content.

Purple

Blue Red

Green Orange

Purple

 

As you can see, all of the elements (div, p, and span) are rendered as boxes. The block elements (div, p) have width that are the size of the viewport, whereas the inline elements (span) have widths the size of their content.

Box Properties

When a box is rendered, the browser must determine the size of the element’s box.  This size depends on the following element box properties:

  • margin
  • border (can be stylized)
  • padding
  • width and height of the element’s content
margin
border
padding
content

 

Each of these properties can be modified to change how the content is rendered.  By default the margin, border, and padding of an element are set to 0.

The margin Property

The margin of an element is the area between the outer border of the element and an adjacent element.  When two adjacent elements have their margins set, the distance between the two element’s borders is the largest margin value of the two, not the sum of the margin values as you might expect.  For example, below, are two span elements each with margins set to 10px.  The space between them is 10px, not the sum of 20px.

span with a 10px marginspan with a 10px margin

 

A margin can be allocated using the margin property as shown below.

/* Set the top, right, bottom, and left margin uniformly */
margin: 10px;

/* Set the top, right, bottom, and left margins separately */
margin: 0px 5px 0px 10px;

There are additional allowable values for the margin property and additional properties that allow you to set the size of the sides independently. See the documentation for details.

Note that changing the margin property of an inline element will change the position of the surrounding text but will not change the position of any surrounding block elements.  In the example, the margin of the span element is set to 500px.  The horizontal spacing of the span element is affected, but not the vertical spacing; that is, the positions of the divs are not affected by the margin value of the span element.

div

span with a 500px margin

div

 

The border Property

The border is the space between the inside of the margin and the outside of the padding.  When a border is allocated it is often rendered with a  predefined style and a color that is different than the background-color of the element.  The width, style, and color of the border can be defined with the border property as shown below.  Note: The border width can not be set to a percentage.

border: 1px;
border: 1px dashed;
border: 1px dashed gray;

There are additional properties that allow you to set the width of the border on each side independently. See the documentation for details.

Just like with the margin property, changing the border property of an inline element will change the position of the surrounding text but will not change the position of any surrounding block elements as shown below.

div

span with a 10px border

div

 

The padding Property

The padding is the area between the inside of the border and the outside of the content.  Padding can be allocated using the padding property as shown below.

/* Set the top, right, bottom, and left margin uniformly */ 
padding: 10px; 

/* Set the top, right, bottom, and left margins separately */ 
padding: 0px 5px 0px 10px;

There are additional allowable values for the padding property and additional properties that allow you to set the size of the sides independently. See the documentation for details.

Just like with the margin and border properties, changing the padding property of an inline element will change the position of the surrounding text but will not change the position of any surrounding block elements as shown below.

div

span with a 15px padding

div

 

The width and height Properties

By default, the width of a block element is set to the width of the viewport and the height is set to fit the content.  For inline elements, the width and height are set to fit the content.

We can modify the width and hight of the content area of a block element by using the width property and the height property respectively as shown below.  Note: the height property can not be set to a percentage and width and height properties have no effect on inline elements.

width: 100%;
height: 50px;

By default, the width and height of the content area is set independently of the padding and border spaces that are allocated (if any).  This often makes it difficult when using percentages to make a child element fit inside its parent element.  We can change the way the width and the height are calculated using the box-sizing property.  See the documentation for details.

There are additional properties that allow you to define the width and height of the content area.  See the width and height documentation for details.

The display Property

As you are aware, each element is, by default, either a block box element or an inline box element.  The display property allows you to change an element’s box type. There are numerous values for the display property, however, for now we only need be familiar with block, inline and inline-block.

  • Block elements are stacked one on top of another with a break before and after them. They can utilize all of the box model properties including width and height.
  • Inline elements do not have breaks before and after them, are arranged horizontally adjacent to one another, and if an inline element has content that cannot fit in the viewport, the element may break and continue on the next row of elements. They can utilize the margin, border, and padding properties but ignore the width and height properties.
  • Inline-block elements do not have breaks before or after them and are positioned adjacent to the element that proceeds them (like inline elements), but can also have their height and width properties set (like block elements).

Below is an example where two internal div elements (in pink) have display set to inline-block and their height properties set to 30px and 60px respectively.

div
This is an inline-block div with 30px height
This is an inline-block div with 60px height
div

Other Box Properties

Below are some other box properties that you might find useful.  The examples above use the background-color property to shade the border, padding, and content area of the boxes.  You can also display an image inside the a box using background-image and adjust the area that the image is displayed in using the background-clip property.

If you find that your text is flowing outside of the element’s box you can set the overflow property to scroll or hidden to avoid this.

The Float Property

The float property allows a block element to float to the left or right of its container without creating a break before and after it.

Below are a few examples showing the effects of using float. They are based on the following HTML.

<div id="div1">div</div>
<p>p with some text</p>
<div id="div2">div</div>

First lets start with an example that does not use the float or display properties. The 3 elements (div, p, div) are block elements and are rendered vertically.

div

p with some text

div

When we change the display property to inline-block they are displayed horizontally.

div

p with some text

div

 

div, p {
    display: inline-block;
}

This same effect can be made by adding float:left to each element and removing the display property.

div

p with some text

div

 

 div, p { 
    float: left; 
}

We can also float the first two elements left and the second div to the right.

div

p with some text

div

 

#div1, p {
    float: left;
}
#div2 {
    float: right;
}

Look what happens when we float the last two elements to the right.  The first HTML element in the source code (p) is floated to the right hand side of the container, then the second div is floated as far right as it can be, which positions it to the left of the p element.

div

p with some text

div

 

#div1 {
    float: left;
}
#div2, p {
    float: right;
}

Without changing the order of the HTML elements, we can position the last two elements to the right (in the original order) by setting the two elements to inline-block, wrapping them in a div, and floating that wrapper div to the right.

div

p with some text

div

 

<div id="div1">div</div> 
<div id="wrapper">
    <p>p with some text</p>
    <div id="div2">div</div>
</div>
#div1 {
    float: left;
}
#wrapper {
    float: right;
}
p, #div2 {
    display: inline-block;
}

Clearing Floats

Consider the following example. Here we have three p elements. The first two are floated left and the third element does not have the float property set. Even though the third element doesn’t float, the float property on the second element prevents a break between the second and third element. Possibly, not what was intended.

paragraph 1

paragraph 2

paragraph 3

 

If we want the third element to be displayed under the two floated elements, we can suppress the the effects of the second p element on the third p element using the clear property.

paragraph 1

paragraph 2

paragraph 3

 

There are three values for clear: left, right, and both. Left suppresses the effects of any float on the left, right suppresses the effects of any float on the right, and both suppresses the effects of any floats on the left and right.

Positioning

By default, elements are stacked vertically or horizontally on the page.  CSS positioning allows us to move an element from its default position, even if the new position makes the element overlaps another element.

The position property has 4 commonly supported values: static, relative, absolute, and fixed. An element is said to be positioned if its position value is anything other than static.

Static

The static value positions an element according to the normal flow.

Relative

An element that has its position property set to relative is positioned relative to its normal position by offsetting its position according to the top, bottom, right, and left properties.

  • The top property adds a vertical offset with positive values moving the position of the element down from its natural top position.
  • The bottom property adds a vertical offset with positive values moving the position of the element up from its natural bottom position.
  • The left property adds a horizontal offset with positive values moving the position of the element right from its natural left position.
  • The right property adds a horizontal offset with positive values moving the position of the element left from its natural right position.

If both the top and bottom properties are set, then bottom property is ignored.  Similarly, if both the right and left properties are set, then the right property is ignored.

If the element overlaps another element we can specify which element is visible using the z-index property.  An element with a higher z-index is positioned over the elements with a lower z-index.

Below are 3 inline-block div elements positioned naturally (with left and right margins).

div
div
div

In the example below, we set its position, top, and left properties.  The element is positioned down and to the right of its natural position.

div
div
div

 

#gray-box div:nth-of-type(2) {
    position: relative; 
    top: 15px; 
    left: 15px;
}

Absolute

No space is added to the natural flow of the document and new stacking layer is created for an element that has its position set to absolute.

It is positioned relative to either:

  • its closest positioned ancestor or
  • the initial containing block (html element) if no ancestor element has been positioned.

The element’s position property is offset from its ancestor’s position according to the top, bottom, right, and left properties.

  • The top property adds a vertical offset with positive values moving the position of the element down from its ancestor’s top edge.
  • The bottom property adds a vertical offset with positive values moving the position of the element up from its ancestor’s bottom edge.
  • The left property adds a horizontal offset with positive values moving the position of the element right from its ancestor’s left edge.
  • The right property adds a horizontal offset with positive values moving the position of the element left from its ancestor’s right edge.

If the height property is set to auto and the top and bottom properties are set, the element will fill the vertical space.  Similarly if the width property is set to auto and the left and right properties are set, the element will fill the horizontal space.

Elements with the position property set to absolute can have margins and the margins do not collapse with the margins of other elements.

In the example below, we set the position property of the gray box div to relative and set the position property of the second div to absolute.  The element is positioned relative to the gray box, below and to the right of the top and left side of the gray box respectively.

div
div
div

 

#gray-box {
    position: relative;
}

#gray-box div:nth-of-type(2) {
    position: absolute;
    top: 15px;
    left: 15px;
}

The z-index property can be set on any positioned element. If a positioned element does not have its z-index property set, it’s set by default to auto, effectively giving it a value of 0. In the example below, the first div’s position property is set to relative and its z-index property is set to 1 and leaves all other element’s z-index unchanged.

div
div
div

 

#gray-box div:nth-of-type(1) {
    position: relative;
    z-index: 1;
}
#gray-box div:nth-of-type(2) {
    position: absolute;
    top: 15px;
    left: 15px;
}

Fixed

No space is added to the natural flow of the document for an element that has its position set to fixed. It is positioned relative to the viewport and is fixed (i.e. does not move) when the page is scrolled.  This allows you to create fixed UI features that remain fixed when the page is scrolled.

The element’s position property is offset from the viewport’s position according to the top, bottom, right, and left properties.

  • The top property adds a vertical offset with positive values moving the position of the element down from the viewport’s top edge.
  • The bottom property adds a vertical offset with positive values moving the position of the element up from the viewport’s bottom edge.
  • The left property adds a horizontal offset with positive values moving the position of the element right from the viewport’s left edge.
  • The right property adds a horizontal offset with positive values moving the position of the element left from the viewport’s right edge.

If the height property is set to auto and the top and bottom properties are set, the element will fill the vertical space.  Similarly if the width property is set to auto and the left and right properties are set, the element will fill the horizontal space.