213

Block formatting context

Slide instructions

SPACEBAR to move forward through slides.

SHIFT & SPACEBAR to move backwards through slides.

LEFT ARROW & RIGHT ARROW to move through sections.

ESC to see overview and ESC again to exit.

F to enter presentation mode and ESC to exit.

Introduction

The block formatting context is important to understand as it affects aspects of the layout including floats, clear, and margins.

Block formatting contexts are laid out in normal flow and behave more or less like any block box, apart from three important exceptions:

  • They contain margins
  • They contain floats
  • They stop elements from sliding under floats

How are they created?

A block formatting context is created if any one of the following properties is applied to a block-level element.

Absolute positioning


p { position: absolute; }
p { position: fixed; }

Floats


p { float: left; }
p { float: right; }

Overflow


p { overflow: hidden; }
p { overflow: auto; }
p { overflow: scroll; }

Display


p { display: inline-block; }
p { display: table-caption; }
p { display: table-cell; }
p { display: flex; }
p { display: inline-flex; }
p { display: grid; }
p { display: inline-grid; }

The flow-root value generates a block container box for the element and establishes a new block formatting context.


p { display: flow-root; }

Contain

The contain property allows an author to indicate that an element and its contents are independent of the rest of the document tree.

This allows browsesr to recalculate the layout for a limited area of the DOM and not the entire page.

Of the seven possible values, three trigger the block formatting context: strict, content and layout.


p { contain: strict; }
p { contain: content; }
p { contain: layout; }

Containing margins

Block formatting contexts will contain the top and bottom margins of child elements.

In the following example, a <div> with a class of example1 has a nested child element with a class of example2.


<div class="example1">
  <div class="example2"></div>
</div>

example2 has the following properties:


.example2 {
  margin-top: 2em;
  margin-bottom: 2em;
  background: lime;
}

The top and bottom margins of example2 will “poke out” the top and bottom of example1.

These margins will affect content above and below example1 but not affect this element directly.

Margins not contained

There are a range of different methods that can be used to contain these margins inside the parent element.

If you add padding or border to the top and/or bottom of example1, these margins will be contained.


.example1 {
  padding-top: 1px;
  padding-bottom: 1px;
}

.example1 {
  border-top: 1px solid red;
  border-bottom: 1px solid red;
}
Margins contained

However, you could also trigger a block formatting context and achieve the same result, without having to add padding or border.


.example1 {
  overflow: hidden;
}
Margins contained

Exercise 1: Write a property to contain margins

Open this HTML file in an editor:
exercises-start/exercise-213-01.html

Write a CSS rule to style the element with a class of example1. Set the following properties:


/* Add styles here */
.example1 {
  background: yellow;
}

This rule sets a background-color on example1.

However, as there is nothing to contain the margins of the child element, example1 will collapse in height until it is the height of the child.

For this reason, you will not see the yellow background for example1.

Write a second CSS rule to style the element with a class of example2. Set the following properties:


/* Add styles here */
.example2 {
  background: yellow;
  border-top: 1px solid red;
  border-bottom: 1px solid red;
}

The borders on top and bottom of example2 will contain the margins of the child element.

Write a third CSS rule to style the element with a class of example3. Set the following properties:


/* Add styles here */
.example3 {
  background: yellow;
  padding-top: 1px;
  padding-bottom: 1px;
}

The padding on top and bottom of example2 will contain the margins of the child element.

Write a fourth CSS rule to style the element with a class of example4. Set the following properties:


/* Add styles here */
.example4 {
  overflow: hidden;
  background: yellow;
}

Adding overflow: hidden will trigger the block formatting context for example4 and will contain the margins of the child element.

Write a fifth CSS rule to style the element with a class of example5. Set the following properties:


/* Add styles here */
.example5 {
  float: left;
  width: 100%;
  background: yellow;
}

Adding float: left will trigger the block formatting context for example5 and will contain the margins of the child element.

Notice that width also needs to be added to example5 in order for this method to be effective.

Write a sixth CSS rule to style the element with a class of example6. Set the following properties:


/* Add styles here */
.example6 {
  display: inline-block;
  width: 100%;
  background: yellow;
}

Adding display: inline-block will trigger the block formatting context for example6 and will contain the margins of the child element.

As with example5, a width also needs to be added to example6 in order for this method to be effective.

Write a seventh CSS rule to style the element with a class of example7. Set the following properties:


/* Add styles here */
.example7 {
  display: flow-root;
  background: yellow;
}

Adding display: flow-root will trigger the block formatting context for example7 and will contain the margins of the child element.

Write an eighth CSS rule to style the element with a class of example8. Set the following properties:


/* Add styles here */
.example8 {
  contain: layout;
  background: yellow;
}

Adding contain: layout will trigger the block formatting context for example8 and will contain the margins of the child element.

Check your work against the finished HTML file:
exercises-finished/exercise-213-01.html

Containing floats

Block formatting contexts will contain floating child elements.

In the following example, a <div> with a class of example1 has a nested child element with a class of example2.


<div class="example1">
  <div class="example2"></div>
</div>

example2 has the following properties:


.example2 {
  float: left;
  width: 100px;
  height: 100px;
  background: lime;
}

As soon as example2 is floated, it will move out of normal flow.

As there are no “in-flow” elements inside example1, the element will collapse until it has no height.

This will make example2 poke out the bottom of example1.

Parent ignores float and height collapses

There are a range of different methods that can be used to force example1 to wrap around example2.

For example, a clearfix solution could be used to solve the problem.


.example1:after {
  content: "";
  display: block;
  clear: both;
}

However, you could also trigger a block formatting context and achieve the same result.


.example1 {
  overflow: hidden;
}
Parent contains float

Exercise 2: Write a property to contain floats

Open this HTML file in an editor:
exercises-start/exercise-213-02.html

Write a CSS rule to style the element with a class of example1. Set the following properties:


/* Add styles here */
.example1 {
  background: yellow;
}

This rule sets a background-color on example1.

However, as there is nothing to contain the child floated element, example1 will collapse in height until it is invisible.

For this reason, you will not see the yellow background for example1.

Write a second CSS rule to style the element with a class of example2. Set the following properties:


/* Add styles here */
.example2 {
  overflow: hidden;
  background: yellow;
}

Adding overflow: hidden will trigger the block formatting context for example2 and will contain the child floated element.

Write a third CSS rule to style the element with a class of example3. Set the following properties:


/* Add styles here */
.example3 {
  float: left;
  width: 100%;
  background: yellow;
}

Adding float: left will trigger the block formatting context for example3 and will contain the child floated element.

Notice that width also needs to be added to example3 in order for this method to be effective.

Write a fourth CSS rule to style the element with a class of example4. Set the following properties:


/* Add styles here */
.example4 {
  display: inline-block;
  width: 100%;
  background: yellow;
}

Adding display: inline-block will trigger the block formatting context for example4 and will contain the child floated element.

As with example3, a width also needs to be added to example4 in order for this method to be effective.

Write a fifth CSS rule to style the element with a class of example5. Set the following properties:


/* Add styles here */
.example5 {
  display: flow-root;
  width: 100%;
  background: yellow;
}

Adding display: flow-root will trigger the block formatting context for example5 and will contain the child floated element.

Write a sixth CSS rule to style the element with a class of example6. Set the following properties:


/* Add styles here */
.example6 {
  contain: layout;
  background: yellow;
}

Adding contain: layout will trigger the block formatting context for example6 and will contain the child floated element.

Check your work against the finished HTML file:
exercises-finished/exercise-213-02.html

Stopping elements from sliding under floats

Block formatting contexts can stop elements from sliding under floats.

In the following example, a <div> with a class of example1 has a nested child element with a class of example2.

example1 also has a nested <p> element with a class of example3.


<div class="example1">
  <div class="example2"></div>
  <div class="example3">Lorem...</div>
</div>

example2 has the following properties:


.example2 {
  float: left;
  width: 100px;
  height: 100px;
  margin-right: 10px;
  background: lime;
}

The <p> element will slide under the floating element.

The line-boxes inside this <p> element will shorten to accommodate the floating element.

This will give the appearance that the text flows beside the float and then wraps below.

Parent contains float

The block formatting context can be used to force the <p> element to sit beside the float so that the text will not wrap below.


.example3 {
  overflow: hidden;
}
Parent contains float

Exercise 3: Write a property to stop elements from sliding under floats

Open this HTML file in an editor:
exercises-start/exercise-213-03.html

Write a CSS rule to style the element with a class of example1. Set the following properties:


/* Add styles here */
.example1 {
  background: yellow;
}

This rule sets a background-color on example1.

However, the element slides under the floated element to the left rather than sitting beside it.

Write a second CSS rule to style the element with a class of example2. Set the following properties:


/* Add styles here */
.example2 {
  overflow: hidden;
  background: yellow;
}

Adding overflow: hidden will trigger the block formatting context for example2 and will force the element to sit beside the float.

Write a third CSS rule to style the element with a class of example3. Set the following properties:


/* Add styles here */
.example3 {
  float: left;
  width: calc(100% - 110px);
  background: yellow;
}

Adding float: left will trigger the block formatting context for example3 and will force the element to sit beside the float.

The calc() value allows you to set a width minus a specific amount. In this case, the width is 100% minus the width of the float and its margin.

Write a fourth CSS rule to style the element with a class of example4. Set the following properties:


/* Add styles here */
.example4 {
  display: inline-block;
  width: calc(100% - 110px);
  background: yellow;
}

Adding display: inline-block will trigger the block formatting context for example4 and will force the element to sit beside the float.

As above, the calc() value is used to set the width.

Write a fifth CSS rule to style the element with a class of example5. Set the following properties:


/* Add styles here */
.example5 {
  display: flow-root;
  background: yellow;
}

Adding display: flow-root will trigger the block formatting context for example5 and will force the element to sit beside the float.

Write a sixth CSS rule to style the element with a class of example6. Set the following properties:


/* Add styles here */
.example6 {
  contain: layout;
  background: yellow;
}

Adding contain: layout will trigger the block formatting context for example6 and will force the element to sit beside the float.

Check your work against the finished HTML file:
exercises-finished/exercise-213-03.html

Russ Weakley

Site Twitter Github Slideshare Linkedin

Next deck

214-01: CSS Property Value syntax