Box model
The “CSS box model“ is a set of rules that define how every web page on the Internet is rendered. CSS treats each element in your HTML document as a “box” with a bunch of different properties that determine where it appears on the page. So far, all of our web pages have just been a bunch of elements rendered one after another. The box model is our toolkit for customizing this default layout scheme.
![](https://dotnetweb30-ke.gitbook.io/~gitbook/image?url=https%3A%2F%2Finternetingishard.com%2Fhtml-and-css%2Fcss-box-model%2Fcss-html-and-the-box-model-9d82a2.png&width=768&dpr=4&quality=100&sign=e57b1365&sv=1)
A big part of your job as a web developer will be to apply rules from the CSS box model to turn a design mockup into a web page.
Back in Basic Web Pages, we briefly touched on how CSS uses “boxes” to define the layout of a web page. Each HTML element rendered on the screen is a box, and they come in two flavors: “block” boxes and “inline“ boxes.
![](https://dotnetweb30-ke.gitbook.io/~gitbook/image?url=https%3A%2F%2Finternetingishard.com%2Fhtml-and-css%2Fcss-box-model%2Finline-vs-block-boxes-f3e662.png&width=768&dpr=4&quality=100&sign=2576e237&sv=1)
All the HTML elements that we’ve been working with have a default type of box. For instance, <h1>
and <p>
are block-level elements, while <em>
and<strong>
are inline elements. Let’s get a better look at our boxes by adding the following to box-styles.css
:
The background-color
property only fills in the background of the selected box, so this will give us a clear view into the structure of the current sample page. Our headings and paragraphs should have gray backgrounds, while our emphasis and strong elements should be light blue.
![](https://dotnetweb30-ke.gitbook.io/~gitbook/image?url=https%3A%2F%2Finternetingishard.com%2Fhtml-and-css%2Fcss-box-model%2Fblock-boxes-and-inline-boxes-7cfa0a.png&width=768&dpr=4&quality=100&sign=8969ac81&sv=1)
This shows us a couple of very important behaviors associated with block and inline boxes:
Block boxes always appear below the previous block element. This is the “natural” or “static” flow of an HTML document when it gets rendered by a web browser.
The width of block boxes is set automatically based on the width of its parent container. In this case, our blocks are always the width of the browser window.
The default height of block boxes is based on the content it contains. When you narrow the browser window, the
<h1>
gets split over two lines, and its height adjusts accordingly.Inline boxes don’t affect vertical spacing. They’re not for determining layout—they’re for styling stuff inside of a block.
The width of inline boxes is based on the content it contains, not the width of the parent element.
changing box behavior
For example, if we wanted to make our <em>
and <strong>
elements blocks instead of inline elements, we could update our rule in box-styles.css
like so:
Now, these elements act like our headings and paragraphs: they start on their own line, and they fill the entire width of the browser. This comes in handy when you’re trying to turn <a>
elements into buttons or format <img/>
elements (both of these are inline boxes by default).
![](https://dotnetweb30-ke.gitbook.io/~gitbook/image?url=https%3A%2F%2Finternetingishard.com%2Fhtml-and-css%2Fcss-box-model%2Fturning-inline-into-block-boxes-772f4c.png&width=768&dpr=4&quality=100&sign=33c29c67&sv=1)
However, it’s almost never a good idea to turn <em>
and <strong>
into block elements, so let’s turn them back into inline boxes by changing their display
property to inline
, like so:
content, padding, border, and margin
The “CSS box model” is a set of rules that determine the dimensions of every element in a web page. It gives each box (both inline and block) four properties:
Content – The text, image, or other media content in the element.
Padding – The space between the box’s content and its border.
Border – The line between the box’s padding and margin.
Margin – The space between the box and surrounding boxes.
Together, this is everything a browser needs to render an element’s box. The content is what you author in an HTML document, and it’s the only one that has any semantic value (which is why it’s in the HTML). The rest of them are purely presentational, so they’re defined by CSS rules.
![](https://dotnetweb30-ke.gitbook.io/~gitbook/image?url=https%3A%2F%2Finternetingishard.com%2Fhtml-and-css%2Fcss-box-model%2Fcss-box-model-73a525.png&width=768&dpr=4&quality=100&sign=a6d72528&sv=1)
padding
The padding
property…you guessed it…defines the padding for the selected element:
![](https://dotnetweb30-ke.gitbook.io/~gitbook/image?url=https%3A%2F%2Finternetingishard.com%2Fhtml-and-css%2Fcss-box-model%2Fincreasing-heading-padding-5a289d.png&width=768&dpr=4&quality=100&sign=c2eb9b67&sv=1)
Sometimes you’ll only want to style one side of an element. For that, CSS provides the following properties:
shorthand formats
![](https://dotnetweb30-ke.gitbook.io/~gitbook/image?url=https%3A%2F%2Finternetingishard.com%2Fhtml-and-css%2Fcss-box-model%2Fpadding-shortform-two-values-a7ed4c.png&width=768&dpr=4&quality=100&sign=f6262698&sv=1)
This means that our previous rule can be rewritten as:
Alternatively, if you provide four values, you can set the padding for each side of an element individually. The values are interpreted clockwise, starting at the top:
![](https://dotnetweb30-ke.gitbook.io/~gitbook/image?url=https%3A%2F%2Finternetingishard.com%2Fhtml-and-css%2Fcss-box-model%2Fpadding-shortform-four-values-93c021.png&width=768&dpr=4&quality=100&sign=9ade2e2&sv=1)
borders
![](https://dotnetweb30-ke.gitbook.io/~gitbook/image?url=https%3A%2F%2Finternetingishard.com%2Fhtml-and-css%2Fcss-box-model%2Fcss-border-syntax-d8ba17.png&width=768&dpr=4&quality=100&sign=e5fcd7cb&sv=1)
Try adding a border around our <h1>
heading by updating the rule in box-styles.css
:
This tells the browser to draw a thin gray line around our heading. Notice how the border bumps right up next to the padding with no space in between. And, if you shrink your browser enough for the heading to be split over two lines, both the padding and the border will still be there.
Drawing a border around our entire heading makes it look a little 1990s, so how about we limit it to the bottom of the heading? Like padding
, there are -top
, -bottom
, -left
, and -right
variants for the border
property:
margins
Margins define the space outside of an element’s border.
Margins and padding can accomplish the same thing in a lot of situations, making it difficult to determine which one is the “right” choice. The most common reasons why you would pick one over the other are:
The padding of a box has a background, while margins are always transparent.
Padding is included in the click area of an element, while margins aren’t.
Margins collapse vertically, while padding doesn’t (we’ll discuss this more in the next section).
margins on inline elements
The horizontal margins display just like we’d expect, but this doesn’t alter the vertical space around our <strong>
element one bit.
![](https://dotnetweb30-ke.gitbook.io/~gitbook/image?url=https%3A%2F%2Finternetingishard.com%2Fhtml-and-css%2Fcss-box-model%2Fmargins-on-inline-elements-4c569c.png&width=768&dpr=4&quality=100&sign=243cc509&sv=1)
If we change margin
to padding
, we’ll discover that this isn’t exactly the case for a box’s padding. It’ll display the blue background; however, it won’t affect the vertical layout of the surrounding boxes.
![](https://dotnetweb30-ke.gitbook.io/~gitbook/image?url=https%3A%2F%2Finternetingishard.com%2Fhtml-and-css%2Fcss-box-model%2Fpaddings-on-inline-elements-fb52d0.png&width=768&dpr=4&quality=100&sign=31826f9&sv=1)
The rationale behind this goes back to the fact that inline boxes format runs of text inside of a block, and thus have limited impact on the overall layout of a page.
vertical margin collapse
Another quirk of the CSS box model is the “vertical margin collapse”. When you have two boxes with vertical margins sitting right next to each other, they will collapse. Instead of adding the margins together like you might expect, only the biggest one is displayed.
For example, let’s add a top margin of 25 pixels to our <p>
element:
Each paragraph should have 50 pixels on the bottom, and 25 pixels on the top. That’s 75 pixels between our <p>
elements, right? Wrong! There’s still only going to be 50px
between them because the smaller top margin collapses into the bigger bottom one.
![](https://dotnetweb30-ke.gitbook.io/~gitbook/image?url=https%3A%2F%2Finternetingishard.com%2Fhtml-and-css%2Fcss-box-model%2Fvertical-margin-collapse-bba78e.png&width=768&dpr=4&quality=100&sign=8c987618&sv=1)
This behavior can be very useful when you’re working with a lot of different kinds of elements, and you want to define their layout as the minimum space between other elements.
generic boxes
Both <div>
and <span>
are “container” elements that don’t have any affect on the semantic structure of an HTML document. They do, however, provide a hook for adding CSS styles to arbitrary sections of a web page.
And here are the associated styles that need to go into box-styles.css
. Most of these should be familiar from the last chapter, although we did throw in a new border-radius
property:
This will give us a big blue button that spans the entire width of the browser:
![](https://dotnetweb30-ke.gitbook.io/~gitbook/image?url=https%3A%2F%2Finternetingishard.com%2Fhtml-and-css%2Fcss-box-model%2Fgeneric-div-for-button-70dc27.png&width=768&dpr=4&quality=100&sign=13f08f8b&sv=1)
content boxes and border boxes
![](https://dotnetweb30-ke.gitbook.io/~gitbook/image?url=https%3A%2F%2Finternetingishard.com%2Fhtml-and-css%2Fcss-box-model%2Fbox-sizing-content-box-09f48a.png&width=768&dpr=4&quality=100&sign=883457d8&sv=1)
SS lets you change how the width of a box is calculated via the box-sizing
property. By default, it has a value of content-box
, which leads to the behavior described above. Let’s see what happens when we change it to border-box
:
This forces the actual width of the box to be 200px
—including padding and borders. Of course, this means that the content width is now determined automatically:
![](https://dotnetweb30-ke.gitbook.io/~gitbook/image?url=https%3A%2F%2Finternetingishard.com%2Fhtml-and-css%2Fcss-box-model%2Fbox-sizing-border-box-ace2be.png&width=768&dpr=4&quality=100&sign=ce35adad&sv=1)
resetting styles
![](https://dotnetweb30-ke.gitbook.io/~gitbook/image?url=https%3A%2F%2Finternetingishard.com%2Fhtml-and-css%2Fcss-box-model%2Fresetting-box-sizing-and-margins-72ff64.png&width=768&dpr=4&quality=100&sign=6d1155af&sv=1)
It’s usually a good idea to override default styles to a predictable value using the “universal” CSS selector (*
). Try adding this to the top of our box-styles.css
file:
summary
With a few key concepts from this chapter, you should feel much more equipped to convert a design mockup into a real-life web page:
Everything is a box.
Boxes can be inline or block-level.
Boxes have content, padding, borders, and margins.
They also have seemingly arbitrary rules about how they interact.
Mastering the CSS box model means you can lay out most web pages.
Last updated