The CSS Box Model is the primary means of layout for everything on the web. It is a standard created by the World Wide Web Consortium which describes layout as rectangular boxes in html which surround every single element on a web page or in the document tree. Using the box model, web designers and developers can make use of various properties such as padding, borders, margin-top, margin-right, margin-bottom, margin-left, and many others to create page layouts. In this tutorial, we’ll take a closer look at the CSS Box Model and why it is so important.
What is the purpose of the CSS Box Model?
The purpose of the CSS Box Model is to define all elements as a box. In other words, everything is a box. Chris Coyier of CSS Tricks describes understanding this concept that every element in web design is a rectangular box was a real “ah-ha moment” for him. Once you have the concept in your mind of this fact, you can begin to use the box model approach with the right mindset.
Why Is the CSS Box Model Important?
If you have ever been creating a page layout for the web and found yourself doing all kinds of math to figure out how wide or tall you can make things and have them behave properly on the page, then you have encountered what it means to deal with the box model. It is important to understand how margins, borders, padding, and content all work together to create the layout of elements on the page.
The Box Model: Content, Padding, Border, Margin
Now that we know everything is a box (Even a box around text), we should as how we can define space between elements, how to define space between content, and how to create different types of borders around elements. You might think of a box as something that comes from Amazon and arrives on your door step. Inside the box is a cool gadget (the content), likely surrounded by some protective padding (the padding). Perhaps two boxes were delivered and they are side by side with a little space in between them. This is the margin. This is kind of like the CSS Box Model!
- Content: Inside the Box, is your content. Of course this may be simple text, images, or other types of media.
- Padding: Padding is what adds space between the content and the edge of the box itself. Padding can be added to any side of the content such as top, right, bottom, and left. Padding is transparent so it will allow background colors to be visible if there are any.
- Border: The border surrounds the content and padding. It may be set to dotted, dashed, solid, double, groove, ridge, inset, outset, none, or hidden. It may also have rounded corners if you like. The key thing to remember is that the border is between the element’s padding and margin and is typically opaque to cover any background color that may be present.
- Margin: Margin is the property that gives space between elements. It can also be applied to the top, right, bottom, and left as the layout calls for it. Interestingly, the margin property can be given a negative value for interesting placement techniques or be set to auto for automatic margins.
Padding Vs Margin
It can be easy to confuse padding and margin as they both give the effect of adding space. But where are these properties adding space? One tip to help remember which is which, is if you find yourself saying “I need more background”, then likely you need some padding. Padding allows the background color through. If you feel you need space between boxes, then that is when margin comes into play. Margin is outside of the border, while padding is inside of the border.
Syntax of Padding and Margin
The syntax for both padding and margin is similar. Often times you see four values side by side like so:
div {
padding: 5px 8px 3px 4px;
}
Now you might look at that and say, ok what number value has what effect? There are two ways to remember this. This first is with an Acronym of TRBL. This stands for Top, Right, Bottom, and Left. So the example above has 5 pixels of padding on the Top, 8 pixels on the Right, 3 pixels on the Bottom, and 4 pixels on the Left. The same holds true for margin. There are a few shorthand options for this, but the only one I like is putting just one value in which applies equally to all four sides.
The other way to remember is by thinking of a clock and moving clockwise.
Margins Auto Collapse
A big difference between padding and margin is that margins will auto collapse. In other words the top and bottom margins of blocks can overlap into a single margin area where the size is the largest of the individual margins. If they are the same margin value on each element, then that value is used: they are *not* added together.
<html>
<head>
<style>
.top {
margin: 0 0 50px 0;
background: lightblue;
}
.bottom {
margin: 50px 0 0 0;
background: lightblue;
}
</style>
</head>
<body>
<h1>Margin Auto Collapse Example 1</h1>
<p class="top">Paragraph 1 has 50px margin Bottom</p>
<p class="bottom">Paragraph 2 has 50px margin Top</p>
<hr>
<p>The distance between Paragraph 1 and Paragraph 2 is 50px (not 100px!)</p>
</body>
</html>
In looking at the example above, you might be tempted to think that gee if I have a margin of 50px on both elements and they are stacked on top of each other, then the result should be a distance of 100px between them. This is not the case thanks to margin auto collapsing. Here is another example.
<html>
<head>
<style>
.top {
margin: 0 0 25px 0;
background: lightblue;
}
.bottom {
margin: 100px 0 0 0;
background: lightblue;
}
</style>
</head>
<body>
<h1>Margin Auto Collapse Example 2</h1>
<p class="top">Paragraph 1 has 25px margin Bottom</p>
<p class="bottom">Paragraph 2 has 100px margin Top</p>
<hr>
<p>The distance between Paragraph 1 and Paragraph 2 is 100px (not 125px!)</p>
</body>
</html>
What values are assigned to Box Model Properties?
So everything is a box, and each box has content, padding, border, and margin. What values get assigned to these properties? This would be units of length such as:
- %: A blocks width such as 50%.
- em: The computed height value of the element’s font-size.
- ex: The height of the character “x” also known as the font’s x-height.
- rem: The font-size of <html> which avoids inheritance issues with em.
- vw: A percentage of the viewport’s width.
- vh: A percentage of the viewport’s height.
- vm: The smaller value of vw and vh.
- px: CSS pixels.
- cm: Centimeters.
- mm: Millimeters.
Diagram Of The CSS Box Model
Below is the diagram of the CSS BoX Model which shows the hierarchy. In fact if you open the developer tools in Google Chrome or Mozilla Firefox, each has a visual representation of the Box Model which updates for every element you may inspect on the page. See! Everything really is a Box!
CSS Box Model Example
Let’s see if we can create a representation of the CSS Box Model on the page using all of the properties we’ve learned about so far.
box-model.html
<!DOCTYPE html>
<html>
<style>
div {
background-color: #cff0fb;
width: 300px;
padding: 15px;
border: 20px solid #737373;
margin: 25px
}
</style>
<body>
<div>
Content
</div>
</body>
</html>
Inspecting The Box Model In Google Chrome
Inspecting The Box Model In Mozilla Firefox
Display Inline vs Block vs Inline-Block
In general, when you’re dealing with layouts using the box model, you are dealing with block level elements. What are block level elements? A block-level element always begins on a new line and takes up the full width of the browser window. The block level elements are <p>, <h1>, <h2>, <h3>, <h4>, <h5>, <h6>, <ol>, <ul>, <pre>, <address>, <blockquote>, <div>, <fieldset>, <form>, <hr>, and <table>.
Block level boxes are perfect for setting dimensions using the width and height properties. In general however, setting a height on an element that contains text or anything sized using font-relative units is a bad idea. The reason is because you may create hidden content with scroll bars on the element – which looks bogus. In any event the following are the key points of block level elements.
Block Level Elements
- In general block elements are bigger.
- Start on a new line.
- Can contain inline elements and other block-level elements.
- Act as structural building blocks.
- As wide as containing element.
- Height adjusts to fit provided content.
Inline elements are different in that they can appear several times on the same line. They do not start on a new line and only take up as much width as needed. In addition to inline elements, we also have inline-block level elements to add another layer of complexity. The easiest way to see the difference between display:inline, display:block, and display:inline-block, is to look at an example. In this snippet below, we will assign the same width, height, and margin to each of the display types.
<html>
<style>
div span {
width: 300px;
height: 100px;
margin: 20px;
background-color: lightblue;
}
div div {
width: 300px;
height: 100px;
margin: 20px;
background-color: lightblue;
}
div p {
width: 300px;
height: 100px;
margin: 20px;
background-color: lightblue;
display: inline-block;
}
</style>
<body>
<h1>Inline</h1>
<div>
<span>I'm a span and I'm inline</span>
<span>I'm a span and I'm inline</span>
</div>
<hr>
<h1>Block Level</h1>
<div>
<div>I'm a div and I'm block level</div>
<div>I'm a div and I'm block level</div>
</div>
<hr>
<h1>Inline-Block Level</h1>
<div>
<p>I'm a p and I'm inline-block level</p>
<p>I'm a p and I'm inline-block level</p>
</div>
</body>
</html>
Even though each pair of elements has the same width, height, and margin, the resulting layout on the page is quite different. Note that on the inline element, both the width and the height are completely ignored. On the block level element, all properties are respected and each element starts on a new line. Lastly, the inline-block element appears to work almost like the block level element with the difference being that they do not need to start on a new line. So if you want to create block like boxes but keep them on the same line, you can use the inline-block property.
Calculating Widths and Heights In The Box Model
If you’re ready to drive yourself bananas, let’s talk about how to correctly calculate the total widths and heights of elements on the page using the box model. The height and width of a CSS box is the size of its content. In addition to this however, you have to account for padding, margins, and borders if there are any. This is likely the cause of troubles if you are expecting one layout based on the dimensions you provide in CSS vs the actual result on the web page. Here is how to calculate.
Box Model Calculations Example
Imagine you want to create three block level boxes on a page, and you want them to take up an equal amount of width so that no matter how skinny or wide the page is, each box will always have exactly 1/3 of the width and be on the same line as each other. First, let’s look at the html markup for this example. Pretty simple stuff. We have three div elements inside of a wrapping div element and some content inside each “box”.
<html>
<head>
<link rel="stylesheet" type="text/css" href="boxy.css">
</head>
<body>
<h1>Box Model Calculations</h1>
<div class="boxes">
<div class="box box1">
<h2>Box One</h2>
</div>
<div class="box box2">
<h2>Box Two</h2>
</div>
<div class="box box3">
<h2>Box Three</h2>
</div>
</div>
</body>
</html>
Here is the CSS for our example.
* {
margin: 0;
padding: 0;
font-family: Verdana, Geneva, Tahoma, sans-serif;
}
h1 {
width: 500px;
background: #303030;
color: #e0e0d1;
text-align: center;
padding: 25px;
border: 15px solid #7da0cc;
margin: 25px 25px;
}
div.boxes {
background-color: #8797a8;
padding: 20px;
}
.box {
float: left;
width: 33.33333%;
padding: 20px;
border: 10px solid lightgray;
}
h2 {
color: gray;
text-align: center;
}
.box1 {
background: lightgreen;
}
.box2 {
background: lightcoral;
}
.box3 {
background: lightskyblue;
}
.boxes::after {
content: "";
display: table;
clear: both;
}
They key thing to note at this point is that we have the float set to left on all the boxes. In addition, each box is exactly 33.33333% wide. So this means, if you have three boxes like we do, then they should each take up an equal amount of space side by side. Check out what is happening in the browser however.
Yep. Just as you would (not) expect. We have two boxes on one line, and the third just kind of hanging out on it’s own line. So what happened? Well, on the .box class, we have a padding of 20px in addition to a 10px border. In the box model, you still have to account for these values! So you say, ok I’ll go ahead and remove the padding and border. Look at what happens then.
So that kind of worked. You got your boxes on the same line, but the look is messed up. You lost your padding and lost the slick border as well. What to do?!
box-sizing: border-box;
Go ahead and put those borders and padding back on your boxes! Once that is complete, we are going to make one small adjustment to our CSS file. In the universal selector area we are going to make use of the box-sizing property and set it’s value to border-box.
* {
margin: 0;
padding: 0;
font-family: Verdana, Geneva, Tahoma, sans-serif;
box-sizing: border-box;
}
What does this do? It tells the browser that when you are setting up the layout on the page, the padding and the border are going to be a part of the total width. So this simplifies your calculations and helps to get the desired layout. Now that we have made the box-sizing change, lets check out the result.
Fun with Borders
Borders can be styled in a whole slew of different ways. Just to recap, borders are the area between the margin and padding. As such you can create outline effects that surround any element. You can apply a border using width
, style
, and color
. This equates to border-width, border-style, and border-color. The commonly used border types are dotted, dashed, solid, double, groove, ridge, inset, and outset.
You can also add color for your borders.
In the examples above, we used a nice little CSS Grid Layout. Here is the HTML and CSS for the gray version.
<html>
<head>
<style>
.grid-container {
display: grid;
grid-template-rows: 145px 145px;
grid-template-columns: 145px 145px 145px 145px;
grid-gap: 30px;
justify-content: center;
}
div {
text-align: center;
padding-top: 30px;
}
.border-style-dotted {
border: 10px dotted gray;
}
.border-style-dashed {
border: 10px dashed gray;
}
.border-style-solid {
border: 10px solid gray;
}
.border-style-double {
border: 10px double gray;
}
.border-style-groove {
border: 10px groove gray;
}
.border-style-ridge {
border: 10px ridge gray;
}
.border-style-inset {
border: 10px inset gray;
}
.border-style-outset {
border: 10px outset gray;
}
</style>
</head>
<body class="grid-container">
<div class="border-style-dotted">10px dotted gray</div>
<div class="border-style-dashed">10px dashed gray</div>
<div class="border-style-solid">10px solid gray</div>
<div class="border-style-double">10px double gray</div>
<div class="border-style-groove">10px groove gray</div>
<div class="border-style-ridge">10px ridge gray</div>
<div class="border-style-inset">10px inset gray</div>
<div class="border-style-outset">10px outset gray</div>
</body>
</html>
Borders Can Be Single Sided
Web designers have the option of assigning a border to the top, right, bottom, or left of an element similar to how margin or padding can be assigned to just a single side. In fact you can combine sides but leave off others for interesting effect as well. For this you can use border-top
, border-right
, border-bottom
, and border-left
. Here is a fun example where we mix and match both different border styles and colors on one element.
<html>
<head>
<style>
div {
width: 700px;
height: 210px;
margin: auto;
text-align: center;
border-top: 20px dotted red;
border-right: 20px dashed green;
border-bottom: 20px solid darkblue;
border-left: 20px double gray;
}
</style>
</head>
<body>
<div>
<p>border-top: 20px dotted red</p>
<p>border-right: 20px dashed green</p>
<p>border-bottom: 20px solid darkblue</p>
<p>border-left: 20px double gray</p>
</div>
</body>
</html>
Round Those Corners!
The border-radius property is a pretty cool tool that allows you to create cool effects and rounded corners on your boxes. At one point, rounded corners were so en vogue that you almost couldn’t tell the difference between a square and a circle! Here we simply set border-radius: 20px;
on our example of the various border styles.
Just like most properties in the box model, you can control all four side – or in the case of border-radius all four corners. There are shorthand techniques but the easiest thing to remember is when specifying all four values the radius will apply to the top-left, top-right, bottom-right, and bottom-left corners. Here is an example where we boost up the border-radius to a whopping 75 pixels to demonstrate the effect.
Further Reading
We covered a lot in this tutorial, but there is of course a whole lot more to know. Here are some good articles and tutorials about the CSS Box Model.
- The W3C CSS Box Model
- Thinking Inside The Box ‒ CSS Box Model
- Introduction to the CSS basic box model
- Css for Beginners: The Css Box Model and How to Use It Correctly
- CSS Box Model for Beginners
- A friendly introduction to padding, borders, and margins
- Unfolding the Box Model
What Is The CSS Box Model Summary
- All HTML elements on a web page can be looked at as Boxes.
- In CSS, the term Box Model refers to the design and layout.
- The Box Model consists of: margins, borders, padding, and the actual content.
- We can change the height and width of elements (boxes).
- The Box Model allows us to define space between elements.
- The Box Model allows us to add borders around elements.