CSS box model once and for all

From time to time, I forget the workings and attributes of the CSS box model. So, this time, I decided to write a blog post summarizing it and highlighting its logic. I hope this will make it easier to retain it.

In order to understand the box model, this post will be broken down in several sections relating to the model attributes. First, we’ll go over the existing types of boxes; then, how they are sized, positioned and floated; finally, how to make them responsive to the screen size.

Types of boxes

With the display attribute we can set the type of box we are using, for example

This div has attribute display: block. The borders are in black, so you can see that it stretches as far as it can to the left and to the right.

This one is a display: inline element. Its contents are wrapped inside a box that can be inlined with other inline elements.

With a display: none style, the element will not be rendered at all. This is different from the visibility: hidden style, in which the elements exist, take space, but are not shown.

Box sizing

The sizing of the box is defined with the width and height attributes. By default, this measure is of the content part only, so additional padding, border or margin add up to the total size of the box. This means that if you want the whole box (content + padding + border + margin) to fit a precise space, you need to do some math.

An alternative to this is to set the sizing measure to box-sizing: border-box. In this mode, the width and height defined will be the sum of the content, padding, border and margin. For example:

This box has width: 300px and
box-sizing: content-box (the default)
As you can see, the content measures 300px, but the border occupies an additional 10px
This other div has width: 300,
but box-sizing: border-box
So 300px is the measure of the entire box!

Since this is a recent addition to the CSS standard, some browser may require specific css tags to switch to box-sizing:

-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
box-sizing: border-box;

To apply this to all elements, just set the CSS style for all elements:

* {
-webkit-box-sizing: border-box;
   -moz-box-sizing: border-box;
        box-sizing: border-box;

Box Positioning

There are 4 attributes for positioning:

  • position: static the element follow the flow of the page and is considered to be not positioned – as a visual reminder, it’s flagged in red. The other attributes, in green, are considered positioned.
  • position: relative the element is translated, with the attributes left, right, top and bottom, relative to where it would be positioned. The element is translated, but it still occupies the original space in the document. In this sense it can overlap other elements and leave blank gaps in the document, as we will see in an example below.
  • position: absolute positions absolutely in relation to the parent box, which must have a positioned attribute (the green ones). It can be positioned using the left, right, top, bottom attributes.
  • position: fixed the element is fixed to the viewport. The box can be positioned using the left, right, top, bottom attributes.

In order to illustrate the types of positioning, some examples:

  • A relatively positioned div
a positioned div (position: relative)
a translated position: relative div overlapping the one above and leaving a blank space where it was located
another positioned div (position: relative)

  • A absolutely positioned div
a positioned div (position: relative)

a div absolutely positioned (position: absolute)

A fixed div… check the bottom right of your screen ๐Ÿ˜‰

I’m a position: fixed div

Floating boxes

An element can be “floated” in order to wrap text around it:

I’m float: left !

In order to demonstrate the text wrapping, I’ll write a text that is long, long, long, long, long, long, long, long, long, long, long, long, long, long, long, long, long, long, long, long, long, long, long, long, long.
As you can see, it wraps around the float!

The problem with the floats is that the following div is still locked on the float:

I’m floated!

This div respect the float and wraps nicely around it.

This next div is locked on the float…

If the next div must break free from the float and appear after the floated element, it suffices to clear: left | right | both the float:

I’m floated!

This div respect the float, but the next one will break free from the float and appear below.

I’m a clear: left div, free from the float!

This float thing can be used to build a responsive web site. Try to resize the screen to see what happen to these divs:

float: left – A
float: left – B
float: left – C

Since they are floated, when there’s no more horizontal space, they are stacked on top of each other. Pretty nice, hum? But there’s more to responsiveness…

Responsive layout

The layout of the page can be changed depending on the size of the viewport using @media queries. When the query is valid, it is triggered, applying the designated styles. For example a menu on the left

Could be stacked on the top of the section when the screen becomes too small:

This is achieved with the following CSS

@media screen and (min-width: 600px) {
   nav     { float: left;
             width: 25%;}
   section { margin-left 25%}

@media screen and (max-width: 600px) {
   nav li  {display: inline }

The first block is applied when the viewport width is at least 600px. It aligns the nav to the left and the section to the top. If the screen size is under 600px, the first block of styling is not applied and the second one is. In this case, the divs will follow the usual behavior of occupying all the horizontal space and being one after the other.

Final Words

I believe this short summary could be used as cheatsheet when in doubt about the box model. I hope you enjoyed it.

A final remark, there’s an upgrade to the box model that is under development: the flexbox. This will be the subject of another post.