CSS Block Formatting Context

Habdul Hazeez - Nov 18 '19 - - Dev Community
_This post was originally published on June 25, 2019 under the title "Introduction to CSS Block Formatting Context". Edited and Published to fit the theme of this series_

We concluded the last post on CSS Floats when i mentioned that floats have a close relationship with Block Formatting Context.

If we recall quite clearly we'll know that floats is used to position an element on the right or left of its container and still remain with the page flow unlike absolute positioned elements that are taken out of flow and placed in a new location using offset properties.

The relationship between these positioning techniques (floats and absolute) is that: Under a given condition they both establish a Block Formatting Context.

One of the main reason a page element can be positioned with float or absolute positioning is when we are dealing with layouts and familiarity with the Block Formatting Context will be an added bonus.

The following snippets will be used in this post with slight modifications along the way. Please save the snippets with the .html and .css extension respectively and make sure the CSS file is linked with the HTML. Remember all HTML snippets should be placed between the start and closing body tag in your HTML.

<div class="parent">
  <div class="child"></div>
  <div class="child"></div>
  <div class="child"></div>
  <div class="child"></div>
  <div class="child"></div>
</div>
Enter fullscreen mode Exit fullscreen mode
.parent {
  margin: 2em auto;
  height: 150px;
  background-color: rgb(200,200,200);
  width: 500px;
}

.child {
  margin: 30px 20px 0 20px;
  width: 100px;
  height: 100px;
  background-color: rgb(250,219,92);
}
Enter fullscreen mode Exit fullscreen mode

And kindly note that all screenshots are from Firefox web browser and its Developer Tools.

With that out of the way. Let's Start.


From the specification:

Floats, absolutely positioned elements, block containers (such as inline-blocks, table-cells, and table-captions) that are not block boxes, and block boxes with 'overflow' other than 'visible' (except when that value has been propagated to the viewport) establish new block formatting contexts for their contents.

This is telling us that for an element to establish a block formatting context it has to be a floated element, absolutely positioned element or block containers that are not block boxes with the overflow property having a value other than visible.

Load the HTML file in your browser, you should get an output similar to the image below:

Yellow boxes shown in Firefox web browser

From the image it's clear that everything is way out of order as the child elements are not contained in their parent element. The reason for this behavior is due to the height of the parent element currently set at 150px and each child element has an height of 100px:

.parent {
  /* Other properties are the same */

  height: 150px; /* Note this */
}

.child {
  /* Other properties are the same */

  height: 100px; /* Note this */
}
Enter fullscreen mode Exit fullscreen mode

This clearly means the parent div can only contain one child element (highlighted in red below) and the remaining child elements will not be accommodated.

Now, remember that one of the conditions to establish a Block Formatting Context is to position the element with float or absolute positioning. We'll be using the float property.

Add the following to the .child CSS rule:

.child {
  /* All properties remain unchanged*/

  float: left; /* Add this */
}
Enter fullscreen mode Exit fullscreen mode

Save the CSS file, and reload the HTML file in your browser, you should get an output similar to the image below:

Floated element shown in the Firefox web browser

Two additional divs are now accommodated in the parent container (highlighted in red).

The other condition to establish a Block Formatting Context is to have the overflow property set to a value other than visible. The question is: Where are we going to put the overflow property?

From the Mozilla Developer Network(emphasis mine):

A block formatting context is a part of a visual CSS rendering of a web page. It's the region in which the layout of block boxes occurs and in which floats interact with other elements.

This means to satisfy the other condition that'll establish a Block Formatting Context, the boxes (the child elements) have to interact with each other inside their parent element.

Armed with this knowledge, the overflow property will have to be applied to the parent element because it contains the floated child elements.

Add the following to the .parent CSS rule:

.parent {
  /* All other properties remain unchanged */

  overflow: auto; /* Add this */
}
Enter fullscreen mode Exit fullscreen mode

Save the CSS file, and reload the HTML file in your browser. You should get something similar to the image below:

Yellow boxes contained in their parent element

All child element are now contained in the parent div container and they are going nowhere (at least for now).

If you take a closer look at the image, you will notice a scroll bar has been added by the browser, this will allow you to scroll the remaining child element into view.

Right click on any child element, and choose “Inspect Element”, click on the third child element in Developer Tools, you should get something similar to the image below

Yellow boxes contained in their parent element

This means this specific child element is still in its initial position (refer to the third image in this article), but it’s now contained in its parent container and other content can be placed after the parent div container.

To demonstrate the last statement, make a copy of the parent div and place it after the initial parent div.

Update your HTML code to match the following:

<div class="parent">
  <div class="child"></div>
  <div class="child"></div>
  <div class="child"></div>
  <div class="child"></div>
  <div class="child"></div>
</div>

<div class="parent">
  <div class="child"></div>
  <div class="child"></div>
  <div class="child"></div>
  <div class="child"></div>
  <div class="child"></div>
</div>
Enter fullscreen mode Exit fullscreen mode

Save the file and refresh in your browser, you should get something similar to the image below.

Yellow boxes contained in their parent element

Right click on the first parent div and click "Inspect Element", click
on the fourth child element, you should get something similar to the image below.

Yellow boxes contained in their parent element

It shows the fourth child element seems to be overlapping with the first child element of the second parent div but they are all contained in their parent due to the Block Formatting Context.

Now one question: What happens if we switch off the Block Formatting Context?

Delete the overflow: auto; property from the .parent CSS rule.

Save the file and refresh your browser. All child element will go out of position.

Yellow boxes contained in their parent element

And if you delete the float property in the child element CSS rule, it gets worse:

Yellow boxes contained in their parent element

Undo the last two changes to your file, everyone plays nice again.

Yellow boxes contained in their parent element

Knowing the Block Formatting Context and how to create one will help you create specific layouts that you might come up with.

Speaking of layouts, we'll be discussing two layout algorithms in this series.

We'll start with Flexbox. Next.

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .