The MDN box model article linked in the previous lesson mentions that different display types have subtly different box models. It also mentions that you can change how a box is calculated by changing the display
property. We will explore the different display values you can use further in this lesson.
This section contains a general overview of topics that you will learn in this lesson.
block
and inline
elements.block
and which elements default to inline
.Most of the elements that you have learned about so far are block elements. In other words, their default style is display: block
. By default, block elements will appear on the page stacked atop each other, each new element starting on a new line.
Inline elements, however, do not start on a new line. They appear in line with whatever elements they are placed beside. A clear example of an inline element is a link, or <a>
tag. If you stick one of these in the middle of a paragraph of text, it will behave like a part of the paragraph. (Like this…) The link’s text will sit alongside other words in that paragraph. Additionally, padding and margin behave differently on inline elements. In general, you do not want to try to put extra padding or margin on inline elements.
Inline-block elements behave like inline elements, but with block-style padding and margin. Inline-block is a useful tool to know about, but in practice, you’ll probably end up reaching for flexbox more often if you’re trying to line up a bunch of boxes. Flexbox will be covered in-depth in the next lesson.
We can’t talk about block and inline elements without discussing divs and spans. All the other HTML elements we have encountered so far give meaning to their content. For example, paragraph elements tell the browser to display the text it contains as a paragraph. Strong elements tell the browser which texts within are important and so on. Yet, divs and spans give no particular meaning to their content. They are just generic boxes that can contain anything.
Having elements like this available to us is a lot more useful than it may first appear. We will often need elements that serve no other purpose than to be “hook” elements. We can give an id or class to target them for styling with CSS. Another use case we will face regularly is grouping related elements under one parent element to correctly position them on the page. Divs and spans provide us with the ability to do this.
Div is a block-level element by default. It is commonly used as a container element to group other elements. Divs allow us to divide the page into different blocks and apply styling to those blocks.
See the Pen block-inline-lesson-div-example by TheOdinProject (@TheOdinProjectExamples) on CodePen.
Span is an inline-level element by default. It can be used to group text content and inline HTML elements for styling and should only be used when no other semantic HTML element is appropriate.
See the Pen block-inline-lesson-span-example by TheOdinProject (@TheOdinProjectExamples) on CodePen.
Now that you understand the basic syntax of HTML and CSS, we’re going to get serious. The most important skills you need to master with CSS are positioning and layout. Changing fonts and colors is a crucial skill, but being able to put things exactly where you want them on a webpage is even more crucial. After all, how many webpages can you find where absolutely every element is just stacked one on top of another?
Learning to position elements on a webpage is not that difficult once you understand just a few key concepts. Unfortunately, many learners race through learning HTML and CSS to get to JavaScript and end up missing these fundamental concepts. This leads to frustration, pain, (and funny gifs) because all the JavaScript skills in the world are meaningless if you can’t stick your elements on the page where you need them to be. So with that in mind, let’s get started.
This section contains a general overview of topics that you will learn in this lesson.
margin
, padding
, and borders
The first important concept that you need to understand to be successful in CSS is the box model. It isn’t complicated, but skipping over it now will cause you much frustration down the line.
Every single thing on a webpage is a rectangular box. These boxes can have other boxes in them and can sit alongside one another. You can get a rough idea of how this works by sticking a border on every item on the page like this:
* {
border: 2px solid red;
}
You can use the browser’s inspector to add the CSS above to this web page if you want. Boxes in boxes!
OK, so there might be some circles in the above image… but when it comes to layout, they fit together like rectangular boxes and not circles. In the end, laying out a webpage and positioning all its elements is deciding how you are going to nest and stack these boxes.
The only real complication here is that there are many ways to manipulate the size of these boxes, and the space between them, using padding
, margin
, and border
. The assigned articles go into more depth on this concept, but to sum it up briefly:
padding
increases the space between the edge of a box and the content inside of it.margin
increases the space between a box and any others that sit next to it.border
adds space (even if it’s only a pixel or two) between the margin and the padding.Be sure to study the diagrams carefully.
margin
property that you’ll find useful. Specifically, the sections about auto
and margin collapsing contain things you’ll want to know.Everything in CSS has a box around it, and understanding these boxes is key to being able to create more complex layouts with CSS, or to align items with other items. In this lesson, we will take a look at the CSS Box Model. You’ll get an understanding of how it works and the terminology that relates to it.
In CSS we have several types of boxes that generally fit into the categories of block boxes and inline boxes. The type refers to how the box behaves in terms of page flow and in relation to other boxes on the page. Boxes have an inner display type and an outer display type.
In general, you can set various values for the display type using the display
property, which can have various values.
If a box has an outer display type of block
, then:
width
and height
properties are respected.width
is not specified, the box will extend in the inline direction to fill the space available in its container. In most cases, the box will become as wide as its container, filling up 100% of the space available.Some HTML elements, such as <h1>
and <p>
, use block
as their outer display type by default.
If a box has an outer display type of inline
, then:
width
and height
properties will not apply.Some HTML elements, such as <a>
, <span>
, <em>
and <strong>
use inline
as their outer display type by default.
Boxes also have an inner display type, which dictates how elements inside that box are laid out.
Block and inline layout is the default way things behave on the web. By default and without any other instruction, the elements inside a box are also laid out in normal flow and behave as block or inline boxes.
You can change the inner display type for example by setting display: flex;
. The element will still use the outer display type block
but this changes the inner display type to flex
. Any direct children of this box will become flex items and behave according to the Flexbox specification.
When you move on to learn about CSS Layout in more detail, you will encounter flex
, and various other inner values that your boxes can have, for example grid
.
Note: To read more about the values of display, and how boxes work in block and inline layout, take a look at the MDN guide Block and Inline Layout.
The example below has three different HTML elements, all of which have an outer display type of block
.
display: flex
. This establishes flex layout for the children of the container, which are flex items. The list itself is a block box and — like the paragraph — expands to the full container width and breaks onto a new line.<span>
elements. These elements would normally be inline
, however, one of the elements has a class of “block” which gets set to display: block
.In the next example, we can see how inline
elements behave.
<span>
elements in the first paragraph are inline by default and so do not force line breaks.<ul>
element that is set to display: inline-flex
creates an inline box containing some flex items.display: inline
. The inline flex container and paragraphs all run together on one line rather than breaking onto new lines (as they would do if they were displaying as block-level elements).To toggle between the display modes, you can change display: inline
to display: block
or display: inline-flex
to display: flex
.https://mdn.github.io/css-examples/learn/box-model/inline.html
The key thing to remember for now is: Changing the value of the display
property can change whether the outer display type of a box is block or inline. This changes the way it displays alongside other elements in the layout.
The CSS box model as a whole applies to block boxes and defines how the different parts of a box — margin, border, padding, and content — work together to create a box that you can see on a page. Inline boxes use just some of the behavior defined in the box model.
To add complexity, there is a standard and an alternate box model. By default, browsers use the standard box model.
Making up a block box in CSS we have the:
inline-size
and block-size
or width
and height
.padding
and related properties.border
and related properties.margin
and related properties.The below diagram shows these layers:
In the standard box model, if you give a box an inline-size
and a block-size
(or width
and a height
) attributes, this defines the inline-size and block-size (width and height in horizontal languages) of the content box. Any padding and border is then added to those dimensions to get the total size taken up by the box (see image below).
If we assume that a box has the following CSS:
.box {
width: 350px;
height: 150px;
margin: 10px;
padding: 25px;
border: 5px solid black;
}
The actual space taken up by the box will be 410px wide (350 + 25 + 25 + 5 + 5) and 210px high (150 + 25 + 25 + 5 + 5).
Note: The margin is not counted towards the actual size of the box — sure, it affects the total space that the box will take up on the page, but only the space outside the box. The box’s area stops at the border — it does not extend into the margin.
In the alternative box model, any width is the width of the visible box on the page. The content area width is that width minus the width for the padding and border (see image below). No need to add up the border and padding to get the real size of the box.
To turn on the alternative model for an element, set box-sizing: border-box
on it:
.box {
box-sizing: border-box;
}
If we assume the box has the same CSS as above:
.box {
width: 350px;
inline-size: 350px;
height: 150px;
block-size: 150px;
margin: 10px;
padding: 25px;
border: 5px solid black;
}
Now, the actual space taken up by the box will be 350px in the inline direction and 150px in the block direction.
To use the alternative box model for all of your elements (which is a common choice among developers), set the box-sizing
property on the <html>
element and set all other elements to inherit that value:
html {
box-sizing: border-box;
}
*,
*::before,
*::after {
box-sizing: inherit;
}
In the example below, you can see two boxes. Both have a class of .box
, which gives them the same width
, height
, margin
, border
, and padding
. The only difference is that the second box has been set to use the alternative box model.
Can you change the size of the second box (by adding CSS to the .alternate
class) to make it match the first box in width and height?https://mdn.github.io/css-examples/learn/box-model/box-models.html
Note: You can find a solution for this task here.
Your browser developer tools can make understanding the box model far easier. If you inspect an element in Firefox’s DevTools, you can see the size of the element plus its margin, padding, and border. Inspecting an element in this way is a great way to find out if your box is really the size you think it is!
You’ve already seen the margin
, padding
, and border
properties at work in the example above. The properties used in that example are shorthands and allow us to set all four sides of the box at once. These shorthands also have equivalent longhand properties, which allow control over the different sides of the box individually.
Let’s explore these properties in more detail.
The margin is an invisible space around your box. It pushes other elements away from the box. Margins can have positive or negative values. Setting a negative margin on one side of your box can cause it to overlap other things on the page. Whether you are using the standard or alternative box model, the margin is always added after the size of the visible box has been calculated.
We can control all margins of an element at once using the margin
property, or each side individually using the equivalent longhand properties:
In the example below, try changing the margin values to see how the box is pushed around due to the margin creating or removing space (if it is a negative margin) between this element and the containing element.https://mdn.github.io/css-examples/learn/box-model/margin.html
Depending on whether two elements whose margins touch have positive or negative margins, the results will be different:
In the example below, we have two paragraphs. The top paragraph has a margin-bottom
of 50 pixels, the other has a margin-top
of 30 pixels. The margins have collapsed together so the actual margin between the boxes is 50 pixels and not the total of the two margins.
You can test this by setting the margin-top
of paragraph two to 0. The visible margin between the two paragraphs will not change — it retains the 50 pixels set in the margin-bottom
of paragraph one. If you set it to -10px, you’ll see that the overall margin becomes 40px — it subtracts from the 50px.https://mdn.github.io/css-examples/learn/box-model/margin-collapse.html
A number of rules dictate when margins do and do not collapse. For further information see the detailed page on mastering margin collapsing. The main thing to remember is that margin collapsing is a thing that happens if you are creating space with margins and don’t get the space you expect.
The border is drawn between the margin and the padding of a box. If you are using the standard box model, the size of the border is added to the width
and height
of the content box. If you are using the alternative box model then the size of the border makes the content box smaller as it takes up some of that available width
and height
of the element box.
For styling borders, there are a large number of properties — there are four borders, and each border has a style, width, and color that we might want to manipulate.
You can set the width, style, or color of all four borders at once using the border
property.
To set the properties of each side individually, use:
To set the width, style, or color of all sides, use:
To set the width, style, or color of a single side, use one of the more granular longhand properties:
border-top-width
border-top-style
border-top-color
border-right-width
border-right-style
border-right-color
border-bottom-width
border-bottom-style
border-bottom-color
border-left-width
border-left-style
border-left-color
In the example below, we have used various shorthands and longhands to create borders. Play around with the different properties to check that you understand how they work. The MDN pages for the border properties give you information about the different available border styles.https://mdn.github.io/css-examples/learn/box-model/border.html
The padding sits between the border and the content area and is used to push the content away from the border. Unlike margins, you cannot have a negative padding. Any background applied to your element will display behind the padding.
The padding
property controls the padding on all sides of an element. To control each side individually, use these longhand properties:
In the example below, you can change the values for padding on the class .box
to see that this changes where the text begins in relation to the box. You can also change the padding on the class .container
to create space between the container and the box. You can change the padding on any element to create space between its border and whatever is inside the element.https://mdn.github.io/css-examples/learn/box-model/padding.html
All of the above fully applies to block boxes. Some of the properties can apply to inline boxes too, such as those created by a <span>
element.
In the example below, we have a <span>
inside a paragraph. We have applied a width
, height
, margin
, border
, and padding
to it. You can see that the width and height are ignored. The vertical margin, padding, and border are respected but don’t change the relationship of other content to our inline box. The padding and border overlap other words in the paragraph. The horizontal padding, margins, and borders move other content away from the box.https://mdn.github.io/css-examples/learn/box-model/inline-box-model.html
display: inline-block
is a special value of display
, which provides a middle ground between inline
and block
. Use it if you do not want an item to break onto a new line, but do want it to respect width
and height
and avoid the overlapping seen above.
An element with display: inline-block
does a subset of the block things we already know about:
width
and height
properties are respected.padding
, margin
, and border
will cause other elements to be pushed away from the box.It does not, however, break onto a new line, and will only become larger than its content if you explicitly add width
and height
properties.
In this next example, we have added display: inline-block
to our <span>
element. Try changing this to display: block
or removing the line completely to see the difference in display models.https://mdn.github.io/css-examples/learn/box-model/inline-block.html
Where this can be useful is when you want to give a link a larger hit area by adding padding
. <a>
is an inline element like <span>
; you can use display: inline-block
to allow padding to be set on it, making it easier for a user to click the link.
You see this fairly frequently in navigation bars. The navigation below is displayed in a row using flexbox and we have added padding to the <a>
element as we want to be able to change the background-color
when the <a>
is hovered. The padding appears to overlap the border on the <ul>
element. This is because the <a>
is an inline element.
Add display: inline-block
to the rule with the .links-list a
selector, and you will see how it fixes this issue by causing the padding to be respected by other elements.https://mdn.github.io/css-examples/learn/box-model/inline-block-nav.html
This section contains helpful links to related content. It isn’t required, so consider it supplemental.