Understanding the CSS Box-Model
By: Elad Shechter
Tags: Front End Development, HTML, CSS, Web Design, Web Development

Understanding the CSS Box-Model

CSS Basics

The box-model is one of the basics things in CSS and HTML. But even in 2020, lots of web developers don’t understand the idea of how box-model behaves.

So, in this article, I will explain the basic logic of the box-model and why it is called the box-model. Besides, I will also give you a deeper insight into the behavior of the box-model.

Indeed, the name ‘box-model’ exists because, in the browsers, everything is built from boxes. So, let’s start exploring these boxes!

Everything is Boxes

Every HTML element is a box that can contain content.

Precisely, there are two basics types of boxes:

⦁ Block boxes

⦁ Inline boxes.

In the past, the Firefox browser had a feature that showed all the container boxes in a 3D visual way. For me, it was one of the best visual examples for beginner web developers in the web industry to understand it.

Firefox 3D debugging (in the past)

Those two types of boxes, were existed from the beginning of the web, let’s talk about them:

Block Boxes

Block boxes, by default, take all the space throughout the width of the container.

The common HTML element for a block box is the <div> HTML element.

Inline Boxes

Inline boxes, by default, take the space according to the content wrapped. The most common HTML element for an inline box is the <span> HTML element.

<div>I'm a DIV</div>

<span>I'm a SPAN</span>

CodePen Example

CSS Display Property for Behavior

The <div> and the <span> elements use the same behavior of basic styles as that of the browser. The behavior of all the boxes comes from the display property of CSS. The basic values of the display property are the inline and the block value.

And here you can guess it right that the <span> HTML element, by default, uses the value of inline while the <div> HTML element, by default, uses the value of block .

div{

display: block; /* browser default styles */

} span{

display: inline; /* browser default styles */

}

And now, if you want, you can change the behavior of every HTML element to your desired behavior.

For example, you can convert it into an opposite behavior:

div{

display: inline;

} span{

display: block;

}

Note: Most of the time, we don’t play with the display like in the last example.

Now, we use the <span> HTML element and more other inline HTML elements, such as the anchor tag of links, <a> , to add some styles for the text.

CodePen Example

Under the Hood of CSS and HTML

Interestingly, all the HTML elements use the display property with the inline value.

You must be wondering how do I know this? And why I’m saying it?

Because every property in CSS has only one default value and for the display property, the initial value is always inline .

You can find this information for the initial value of every property of CSS in the MDN of Mozilla.

The Big Question

Now the question that we need to ask ourselves is that:

Why does the HTML element of <div> behave with the display: block value?

The answer is in the browser’s user-agent-stylesheet. So, let’s talk about it.

The Browser User-agent-stylesheet

When we create web pages, the browser loads its own CSS stylesheet before we even load a single line of CSS.

And here comes the funny part:

All the HTML elements which by default have a value of block , this is only because the browser decides to add them the display property with a value of block .

Let me repeat it; these styles aren’t the default styles of CSS. And if we reset a <div> HTML element to its initial display, it will become equal to inline .

The only reason that we have those differences between different kinds of HTML elements is that the browser loads its own CSS, and we have become used to it.

div{

display: initial; /*= equal to inline */

}

To get an idea of how the browser’s user-agent-stylesheet looks like, you can take a look at the WebKit user-agent-stylesheet of Chrome.

Now, if you want to know more about the initial value and other CSS reset keywords value, you can read my previous article “Understanding the “Initial”, “Inherit” and “Unset” CSS Keywords”.

Controlling the Box-model

Every HTML element is a box that we can control on the outside space with the margin property.

After that, we can give it a border .

Here, with the padding property, we can also provide the inner spaces between the content and the border inside the box.

The funny image from Kelly Vaughn in her twitter account explains the box-model in the best way.

Demonstration of the Box model by Kelly Vaughn

Styling the Box

In CSS, we can control the view of the HTML elements of the box according to all its parts i.e., content, padding, border, and margin.

Padding

Padding is the inner space between the content and the border of the box. You can use the same value all across the box, for example, padding: 20px; or you can give padding to only one side of the box, for example, padding-right: 10px; .

Besides, there are options for shorthand writing, which allow you to give a different value to each side, without writing them separately.

For example, padding: 10px 20px 5px 15px; , equal to padding-top: 10px , padding-right: 20px , padding-bottom: 5px and padding-left: 15px .

And there are even more possibilities for writing shorthand.

Examples for writing way for padding:

padding-top: 10px;

padding-right: 20px;

padding-bottom: 25px;

padding-left: 5px;

/* all 4 values eqpal to this */

padding: 10px 20px 25px 5px; padding: 10px; /* Apply to all four sides */

padding: 10px 20px; /* vertical | horizontal */

padding: 10px 20px 30px; /* top | horizontal | bottom */

Borders

There are a lot of possibilities for styling borders in 2020. However, there are two basic styles for seeing the border on HTML elements.

Precisely, there are quite a lot of properties for creating a border. The three basic properties for creating borders are:

border-style - mostly used with one of the common keywords: solid , dashed or dotted .

- mostly used with one of the common keywords: , or . border-width , tells the browser about the size of the border. Usually, we use pixel value for this property, for example, border-width: 5px; .

, tells the browser about the size of the border. Usually, we use pixel value for this property, for example, . border-color , by default, the value uses the currentColor of the text. However, we prefer to define it even if we don’t have to. For example, border-color: red; .

Most of the web developers don’t use those three properties separately. Instead, there is a shorthand that gives you the possibility to write all of them together, the border shorthand property.

With this property, we can write only border: solid 5px red .

border: solid 5px red;

CodePen Border Example

Interestingly, we can control on every side of the padding in the same way we control all the sides of the borders separately.

In fact we can also control and give a different style to each part of the borders, for example:

border-width: 5px 10px 15px 20px;

border-style: solid dashed dotted double;

border-color: red green blue brown;

CodePen Different Types of Borders Example

Margins

Margins are the outer spaces between boxes.

But these outer spaces can’t get other styles, for example, the background color.

The values of margin property, works in a similar way like the padding property, with all the same shorthands:

margin-top: 10px;

margin-right: 20px;

margin-bottom: 25px;

margin-left: 5px;

/* all 4 values eqpal to this */

margin: 10px 20px 25px 5px; margin: 10px; /* Apply to all four sides */

margin : 10px 20px; /* vertical | horizontal */

margin : 10px 20px 30px; /* top | horizontal | bottom */

Collapse behavior

Now, when two HTML block elements have vertical margins, and these two margins collapse into one, here the bigger will dominate.

Here, this visual example is the best way to understand it:

Collapse Margins CodePen Example

Understanding the Sizing of Boxes

By default, the width: auto value of HTML block elements, is equal to the width of the row.

But we can also give a specific width value to the HTML elements, for example, width: 300px; .

Where Developers Fail to Understand the Box-model?

This basic calculation is straightforward when you only give the width for an HTML element.

But in a real project, you provide HTML elements with width and padding and sometimes borders too.

In this calculation, most of the junior developers fail to understand the basics of how sizing works in browsers.

The Tricky Question

The tricky question for beginner developers is about the width size of an HTML element which has width: 300px , padding: 10px and border: solid 2px green ?

.box{

width: 300px;

padding: 10px;

border: dashed 2px green;

}

The conventional thinking is that the width includes the padding and the borders.

But it wasn’t like that at the beginning of the web browsers.

And if you gave those properties: width of 300px + two sides of padding (20px) + two sides of borders (4px), it meant that the box HTML element size was equal to 324px.

Example:

Total width equal to 324px

CodePen Example

Honestly, this way of calculation size isn’t intuitive.

And then in 2009/2010 came a new property to CSS, the box-sizing property, that changed all this behavior.

The New box-sizing Property

The box-sizing property gives you the possibility to tell the browser what size property (width or height) is included.

By default, it included only the content ( content-box value).

But now, you can tell the browser to include the padding and the borders in the calculation with the new value of border-box .

content-box - include only the content.

- include only the content. border-box - include content + padding + border.

This new possibility is a lot more intuitive to include the padding and the border in the size of the HTML element.

Resetting Everything to Border-box

In 2020, it is better to reset all the HTML elements to the border-box value. This, in most cases, is a better way to calculate size.

Because it is easier, we can now see that in a lot of new websites, adding in the CSS Reset styles, reset for all HTML elements will behave as box-sizing: border-box .

Resetting all HTML elements:

*,

*::before,

*::after{

box-sizing: border-box;

}

This way if we give an HTML element a width: 300px , padding: 10px , border: solid 2px green and box-sizing: border-box , the total width of this element will be 300px (and not 324px).

It also means that the content will shrink in this case to 276px width.

CodePen example of box that include box-sizing: border-box

Side by Side, both box-sizing methods: