Formatting Contexts Explained

In this guide I have often referred to the Block and Inline formatting contexts, and how elements behave when part of these contexts. In this guide I will detail what the formatting contexts are, and how we can make use of the way that they behave.

The Formatting Context

Everything on your page is part of a formatting context, this is essentially an area which has been defined to lay out content in a particular way. Therefore a Block Formatting Context will lay child elements out according to Block Layout rules, a Flex Formatting Context will lay its children out as flex items. Each formatting context has specific rules about how layout behaves when in that context.

The Block Formatting Context

The html element defines the initial Block Formatting Context (BFC) for your page. This means that all of the elements inside <html></html> lay themselves out according to Normal Flow following the rules for block and inline layout. Elements that are participating in a BFC use the rules outlined for the CSS Box Model which define how their margins, borders and padding interact with other blocks in the same context.

Creating a new Block Formatting Context

The html element is not the only element capable of creating a new BFC. Other CSS properties will create a BFC too. This is useful because a new BFC will behave much like our document, and will become a mini-layout inside the main layout. A BFC will contain everything inside it, float and clear will only apply to items inside the same formatting context, and margins only collapse between elements in the same formatting context.

In addition to the root element of our document (the html element) a new BFC is created in the following situations:

  • floated elements
  • absolutely positioned elements (including position: fixed and position: sticky
  • elements with display: inline-block
  • table cells or elements with display: table-cell, including anonymous table cells created when using the display: table-* properties
  • table captions or elements with display: table-caption
  • block elements where overflow has a value other than visible
  • display: flow-root
  • elements with contain: layoutcontent, or strict
  • flex items
  • grid items
  • multicol containers
  • elements with column-span: all

We can have a look at a couple of these in order to see the effect that creating a new BFC has. In the below example I have a floated element, it is inside a div with a border applied, and the content of that div has floated alongside our float. As the content of the float is taller than the content alongside it, the border of the div now runs through the float. As explained in the guide to in-flow and out of flow elements, the float has been taken out of flow and so the background and border of the div only contain the content and not the float.

Create a new BFC would contain the float, and a typical way to do this in the past has bee not set overflow to overflow: auto or see other value than the initial value of visible.

This creates a new BFC, which contains the float. Our div now becomes a mini-layout inside our layout and any child elements will be contained inside it. The problem with using overflow to create a new BFC is that the overflow property is really for telling the browser how you wish to deal with overflowing content. There are some occasions where you will find you get unwanted scrollbars or clipped shadows when you use this property purely to create a BFC. In addition it is potentially not very readable for a future developer, as it may not be obvious why you used overflow in such a way. If you do this it would be a good idea to comment the code to explain.

Using display: flow-root

A newer value of display gives us the ability to create a new BFC without any other potentially problematic side-effects. Using display: flow-root on the containing block will create a new BFC.

Now everything inside that container participates in the block formatting context of that container, and floats will not poke out of the bottom of the element.

The value name of flow-root makes sense when you understand that you are creating something that acts like the root element (html) in terms of how it creates a new context for the flow layout inside it.

An inline formatting context

Inline formatting contexts exist inside other formatting contexts and can essentially be thought of as the context of a paragraph. The paragraph creates an inline formatting context, and inside that things such as strong, a, or span elements are used on the text.

The Box Model does not fully apply to items participating in an inline formatting context. In a line in a horizontal writing mode, horizontal padding, borders and margin will be applied to the element and push the text away left and right. However margins above and below the element will not be applied. Vertical padding and borders will be applied but will end up overlapping content above and below as in the inline formatting context the line boxes will not be pushed apart by padding and borders.

Other formatting contexts

While I am covering flow layout in this guide and therefore not referring to other possible formatting contexts, it is useful to understand that creating any kind of formatting context will then change the way that the elements inside that formatting context behave, this behaviour is always described in the specification and also here on MDN.

Summary

In this guide we have looked in more detail at the Block and Inline formatting contexts and the important subject of creating a BFC. In the next guide we will find out how normal flow interacts with different writing modes.

See Also

Document Tags and Contributors

Contributors to this page: rachelandrew
Last updated by: rachelandrew,