How the CSS box model works

Image by ThoughtCo from article Life and “Work of Piet Mondrian, Dutch Abstract Painter

When laying out a document, the browser's rendering engine represents each element as a rectangular box according to the standard CSS basic box model. CSS determines the size, position, and properties of these boxes. How does it work?

Table of Contents

  1. Introduction
  2. Box model areas
  3. Distinguishing areas
  4. Margin collapsing
  5. Box Sizing
  6. Box model settings
  7. Takeaway

Introduction

The basis of content distribution on the web is rooted in the box model. It describes the rectangular fields that are generated for all elements in the document tree (DOM). This phenomenon is handled by the browser rendering engine.

Every HTML element in a document is a rectangle (or box). As can be seen in the figure, the content is wrapped in three areas that have a given order and whose properties can be changed using CSS: padding, border and margin.

Image by Sahand Babali on Unsplash

These areas are always part of every element in the document, even if they are not defined in the style sheet. In that case, they have either a value of zero or no value. For each of these properties, including content, we can set the size, type, positioning, and relationship to other elements, as well as add external information.

Box model areas

The CSS box model is a container that contains multiple properties including borders, margin, padding, and the content itself. It is used to create the design and layout of web pages. It can be used as a toolkit for customizing the layout of different elements. Web browsers render every element as a rectangular box according to the CSS box model. The CSS box model has four parts.

Visual representation of the CSS box model.

Content

The element's content is located inside the boundary of this area. It can be text, an image, a video, or any other element in a document. Both the width and the height are indicated by the size of the content. Content can only be manipulated for pseudo-elements.

Visual representation of the content in the CSS box model.

Padding

The inner edge of the element (padding) reserves space around the content area (content) within the border. Padding is therefore an indentation inside the element itself.

Visual representation of the padding in the CSS box model.

Border

The border of the element is located between the area of the inner edge (padding) and the outer edge (margin). Its appearance can be adjusted according to the user’s design preferences.

Visual representation of the border in the CSS box model.

Margin

The area of the outer margin expands the space around the element from the border. This is an empty space that is used to separate one element from another.

Visual representation of the margin in the CSS box model.

Distinguishing areas

The content and border areas are rarely confused. In the first case it is the content of the element and in the second it is its boundary. However, there is often a misunderstanding of the use of inner and outer indentation.

Both properties (padding and margin) are used to create empty space around the content of the elements and it can therefore be easy to confuse them or not take their different behaviors into account. The difference is in the way gaps are created and used.

Use of padding

padding, or internal indentation, defines the distance between the element, the content, and the border. It is used for indenting elements in containers, for internal indentation of two or more elements. This can be used, for example for increase the space around the text of the buttons.


p {
  padding: 10px;
}

Padding area is the space between its content and its border. It creates extra space within an element.

Use of margin

Margin, or outer indentation, is the personal space of an element. Margin is used in cases where empty space is needed around the element, as an offset from surrounding elements. It can also be used for alignment inside the element in the vertical and horizontal directions (auto value). And unlike all previous features, margin has no effect on the dimensions of the box model.


p {
  margin: 10px;
}

Margin area is the space around an element. It creates extra space around.

In addition, margin has another specific behavior –⁠ its vertical values merge in certain cases. This behavior is called margin collapsing.

Margin collapsing

Margin has one special behaviour –⁠ margin collapsing. Let's define when it occurs. The outer edges of two elements merge if the following conditions are met:

  1. Both elements are block elements
  2. The merging elements are either top or bottom margins (merging does not apply to margin-left and margin-right)
  3. The elements in the structure are at the same level of the DOM structure and there is no separating content between them
  4. The elements are in a parent-child relationship and have an internal indentation or boundary defined
  5. The float property is not applied to the element
  6. Elements do not have an absolute positioning set

You can find an even more detailed description on the MDN page.

Collapsing behavior

Merging is designed to make it easy to define vertical margins for multiple consecutive elements in the content.

This behavior is useful, for example, when designing a blog article, which contains various elements for which we want to have a unified indent. Figures, tables, headings, paragraphs, and other elements can have the same outer indent, regardless of the order in which they follow each other. As a result, we don't have to define offsets for each combination.

Examples of collapsing

In short, we can say that the edges merge when two vertical edges (top and bottom) come into contact with each other. Then the merge occurs and only the larger indent value is applied. We can imagine it as a duel of two outer edges, where the bigger one wins.

If the offset values are for both of the same elements, only one remains, or both values are merged into one:

Parent dominance

Merging also occurs for elements when their parent element has a defined outer edge in the vertical direction as well as elements inside. In this case, however, it depends on what properties the elements have inside.

If the elements inside the parent element have a padding or border property set, the outer indent will not be merged. Take a look at the example on CodePen, where nested elements have an internal offset:

Negative values

Merge works the same for negative outer offset values. The calculation just must be done carefully.

If one outer offset value is negative, it is subtracted from the positive value. Therefore, if a margin-bottom is set to -50px and an element with a margin-top of 100px follows, the resulting value of the offset will be 50px after merging. You can try this example again on CodePen.

The same principle applies when we combine two negative offsets. Again, a higher (in this case more "negative" or better absolute) value is applied after the merger.

Box Sizing

box-sizing, a property that defines how the width and height of an element are calculated, is set to content-box by default in browsers. However, there is another value that changes the behavior of the element size calculation: border-box. Historically, the padding-box value also appeared in the specification, but it has since been removed and no longer exists in today's specification. It calculated the size of the box by summing the content and padding areas without a border.

Content-Box

The width and height calculation of an element is given by the sum of the content, padding, and border areas. The margin property does not affect the resulting size of individual elements.

This means that if the width and height of the element are set, the values of the padding and border properties will expand the total size of the box by the sum of their values. This behavior corresponds to the CSS setting of box-sizing: content-box property.

See the Pen Box Model: Content-Box by Ondřej Konečný (@ondrejko) on CodePen.

Border-Box

For this type of model, the defined width and height are equal to the resulting box size, regardless of the values of the padding or border properties. Again, the margin property does not affect the resulting size of the element. This behavior corresponds to the CSS setting of box-sizing: border-box property.

See the Pen Box Model: Border-Box by Ondřej Konečný (@ondrejko) on CodePen.

Box model settings

Today, setting up a single box model for all elements is the best possible solution. And there is a simple explanation for this. All elements on the site are handled the same, so their behavior is consistent throughout the document.

In addition, web design tools work with the same elements, making it easier for the designer and coder to collaborate. Decorations such as frames do not affect the defined dimensions of the elements, and the elements on the resulting site should behave in the same way.

It is recommended to set the box-sizing property to value border-box. This is straightforward and intuitive, but we must set this rule manually in the font, because the content-box value still remains the default setting for backward compatibility.

However, there are exceptions when it is recommended to set the content-box value for the box-sizing property. For relative or absolute positioning, this setting ensures that the positioning setting values are relative to the content, independent of frame or indent changes.

The following rule has thus been added to the basic style, which is now a common practice:


*, *::before, *::after {
  box-sizing: border-box;
}

Jon Neal came up with a certain alternative that also seems to be valuable. Instead of resetting the box-sizing property on the border-box for all elements, it sets it only to the root element of the document. For other elements, it uses the inherit value, which allows the box-sizing property to inherit:


html {
  box-sizing: border-box;
}
*, *::before, *::after {
  box-sizing: inherit;
}

This can be useful when designing a component that assumes the default box-sizing: content-box behavior, and elements embedded inside. This can prevent unwanted breakage of nested components.

Takeaway

The behavior of the box model is a bit confusing due to its development. This is evidenced by the fact that the International Box-Sizing Awareness Day was established on February 1st.

Due to backward compatibility, default browser settings have the box-sizing property set to content-box, even though the vast majority today use the border-box value. Therefore, we should not forget to define the behavior of the box model in our stylus, as well as to understand the differences between these values.

It is worth mentioning that it is up to each individual whether he or she will use one calculation method or the other. Rather, it is important to understand the principles of operation and use them where they suit the user. Each method has its pros and cons.

Back to Top