HTML elements are treated as boxes in CSS and the manner and way these elements are arranged on a web page are governed by the CSS box model which is a set of rules that define how web page are rendered.
Having a good understanding of the box model will aid you in creating your desired layout.
Now, you might ask: How come an HTML element is treated as a box in CSS?
Create your HTML and CSS files to follow along. Make sure your CSS file is properly linked with the HTML. If you have read previous posts in this series, you should know by now that all HTML code snippets will be inside the body
tag.
Given the code snippets below:
<h1>Header 1</h1>
<h2>Header 2</h2>
<div>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit aliqua.</p>
</div>
<ul>
<li>One</li>
<li>Two</li>
<li>Three</li>
</ul>
<span>Lorem ipsum dolor sit amet, consectetur adipi</span>
<span>Lorem ipsum dolor sit amet, consectetur adipi</span>
* {
outline: 3px solid #1560bd;
margin-bottom: 1.5em;
background-color: #f9f9fa;
}
Save your files and load the HTML in your browser.
From the image above It's evident that elements appear in rectangular shapes, with some element spanning the entire width of the page e.g h1
, li
and some occupying just a fraction of the page e.g the span
element. Why? you might ask.
In CSS these boxes are classified into two:
- block boxes
- inline boxes
BLOCK BOXES
If a box is defined as a block, it will extend in the inline direction to fill space available in its container (i.e its parent) and the elements that generate this type of boxes are called block level element. Examples include div
, h1
, li
e.t.c. Some other characteristics of these boxes are:
- They will break into a new line if need be.
- Their width and height properties will apply
- Padding, margins, and the border will cause other elements to move away from the box
This behavior of block boxes can be changed in CSS with the display
property which accepts values like inline
, flex
, grid
. Let's take an example.
Update your CSS to match the snippets below:
* {
outline: 3px solid #1560bd;
margin-bottom: 1.5em;
background-color: #f9f9fa;
display: inline; /* Add this */
}
Save and Refresh your browser, all page elements will be rendered on a single line and will break into a new line if the available space is not enough.
INLINE BOXES
As their name suggests these boxes will be rendered on a line and by default the width and height properties will not apply. Other behaviors of these boxes include:
- Padding or margin will not cause other elements to move away from the box
- They will not break into a new line
Just like block boxes, inline box behavior can be changed using the display
property.
Add a class
attribute to the span
elements in your HTML:
<span class="block">The first SPAN element</span>
<span class="block">The second SPAN element</span>
Update your CSS to with the snippet below:
span.block {
display: block;
outline: 3px solid red;
}
Save your files and refresh your browser.
The display: block
can be applied to other inline elements like a
(link), em
, strong
e.t.c.
With that out of the way, these boxes in CSS are made of four main parts. They are:
- Content
- Padding
- Border
- Margin
CONTENT
The is the text, images, or other media content contained in the element.
PADDING
This is an internal spacing that exists between the boundary of the element and the element's edge. And the element edge itself can have a border. Confused? Let's code.
Update your HTML and CSS to match the following snippet:
<header>
<h1>THIS IS H1</h1>
</header>
header {
border: 2px solid #1560bd;
}
h1 {
padding: 2em;
}
Save your files. Refresh your browser, and perform the following steps:
- Use "Inspect Element" on the
h1
element - Navigate to the Layout tab
- Click on the Box Model
- Hover your mouse (or pointing device) over the inner purple box
- the browser will let you know it's the padding and the corresponding element will be highlighted on the web page.
From the box model, you will observe that the padding value is applied to all four sides of the box. Why is this happening? That's because the padding
property is actually shorthand for:
padding-top
padding-bottom
padding-right
padding-left
And it gets interesting, if you supply two values to the padding
property, the browser will use the first value for the top and bottom, and the second value for the right and left. Say What?
h1 {
padding: 2em 2em;
}
But what happens if we supply three values? the first value will be used for the top, the second value will be used for the right and left, and the third value will be used for the bottom.
h1 {
padding: 2em 3em 2em;
}
You can use the browser Developer Tools to confirm this:
BORDER
The is the line between the box’s padding and margin. For a code sample, check the code in the explanation on padding (specifically the border
property declaration of the header
element). Repeat the steps to show the Box Model, but this time hover your mouse (or pointing device) over the area that's colored black. This is the border, the browser will do the rest
Just like the padding property, the border
can be used to declare all four sides of the border at once. The sides are:
border-top
border-right
border-bottom
border-left
But unlike padding, you cannot declare different border width of all four border sides with the border
property, you will have to explicitly change each side border width. This means
header {
border: 1px solid green; /* this is valid */
}
IS NOT THE SAME AS
header {
border: 2px 3px solid green; /* this is invalid */
}
You will have to do this instead:
header {
border-top: 3px dashed green;
border-right: 1px solid red;
border-bottom: 5px solid gold;
border-left: 4px solid maroon;
}
MARGIN
The margin controls the space between different elements on a page. Repeat similar steps as the explanation on border and padding, but in this case, you should hover your mouse (or pointing device) over the yellow area, this is the margin.
The margin
property is also short for four other properties:
margin-top
margin-right
margin-bottom
margin-left
The margin property behaves similarly to the padding
property and you can supply one, two or three values and the browser will do the rest.
This parts (content, padding, border, and margin) apply to block-level elements and inline elements with the display
property set to block
.
These parts are summed up in the image below:
The paddings, borders, margins and the content of an element allow the rendered box to occupy a specific width and height on the page, most of the time you will have to know how to calculate the width and height of an element to make sure your web page is displayed correctly in all browsers.
When it comes to this calculation you should have it in mind that there are two box models in CSS. They are:
- The standard box model
- The alternate box model
THE STANDARD BOX MODEL
From the Mozilla Developer Network:
In the standard box model, if you give a box a width and a height, this defines the width and height of the content box_. Any padding and border is then added to that width and height to get the total size taken up by the box
This translates to: In the standard box model if you define a width and height for an element it becomes the height and width of the content box. What is the content box?
The content box is the box that contains the content of a page element. For example if you have the following HTML:
<p>This is a paragraph</p>
The content will be the phrase "This is a paragraph". You can use the browser Developer Tools to confirm this. If you have your HTML opened in your browser, perform the following steps:
- Use "Inspect Element" on a paragraph element
- Navigate to the Layout tab
- Click on the Box Model
- Hover your mouse (or pointing device) over the innermost part of the box (the blue part)
- The Developer Tools will show the word content and the corresponding content will be highlighted on the page.
Now, let's take an example to show how the browser performs its calculation in this box model.
Update your HTML and CSS to match the following snippets.
<div class="box">
<p>Lorem ipsum dolor sit amet, consectetur adipisicing
elit, sed do eiusmod
tempor incididunt ut labore et dolore magna aliqua.</p>
</div>
.box {
width: 350px;
height: 150px;
margin: 25px;
padding: 25px;
border: 5px solid #1560bd;
}
Looking at the snippet above, How much space will our box take? If you answered 350
, am sorry, it's not the correct answer, but you are definitely close.
The element will take up the space of 410px
and a height of 210px
. How?
Save your files and refresh your browser. Use "Inspect Element" on the paragraph, and navigate to the Layout tab and click on the Box Model, you should have an output similar to the image below.
How did the browser arrive at this value(s)? If you take your time and observe, you'll figure it out. But all the same, time for some math.
To measure how wide our element is, we start calculating from the left border to the right border. Now observe the image below:
When you sum the highlighted value from the image above:
- 5 + 25 + 350 + 25 + 5 => 410 (the width value computed by the browser)
To calculate the height, we start from the top border to the bottom border.
Summing up the highlighted value in the image above:
- 5 + 25 + 150 + 25 + 5 => 210 (the height value computed by the browser)
In some cases, you might not want the default standard box model calculations. Which brings us to the alternate box model.
THE ALTERNATE BOX MODEL
The alternate box model was introduced sometime after the standard box model. Using this model, any width is the width of the visible box on the page, therefore the content area width is that width minus the width for the padding and border. Say What? Take a deep breath. Exhale. Now read on.
This alternate box model is not enabled by default compared to the standard box model which is the default model used in web browsers.
To use the alternate box model, you will have to tweak your CSS with the box-sizing
property.
Update your CSS to match the snippet below.
.box {
width: 350px;
height: 150px;
margin: 25px;
padding: 25px;
border: 5px solid #1560bd;
box-sizing: border-box; /* Add this */
}
Save your file, and refresh your browser. Perform the usual step to show the Box model in the Developer Tools and you should have an output similar to the image below.
If you sum up the highlighted values in the box you will get the same width
value computed by the browser.
The browser is now using the width and height values we explicitly specified in our CSS i.e 350px
and 150px
. Why? When you declared the box-sizing
property with a value of border-box
you are telling the browser:
to take the border box as the area defined by any size you set.
The border box is the area from the left border to the right border. And the browser gladly obeyed, by using the width specified in our CSS.
Using the alternative box model is a common choice among developers (myself included) and to make it work for all elements in the web page, we'll have to set the box-sizing
on the html
element and set all other elements to inherit that value as depicted in the snippet below.
html {
box-sizing: border-box;
}
*,
*::before,
*::after {
box-sizing: inherit;
}
ASIDE: Internet Explorer used to default to the alternative box model, with no mechanism available to switch.
We talked about margins in this post, but there is a gotcha that you need to watch out for, and that is the concept of Margin Collapsing. That's next.