Diving into CSS display modes

Published: October 1st, 2020

While layouting pages one can get easily confused with the different behaviour of elements. If you work on a large codebase where overwriting the display properties of elements happens a lot, things can easily get out of hand. So let's get back to the basics and get a clear understanding of the different elements and display modes.

Let's begin with a CodePen which contains all the examples I will explain below:

See the Pen Display attributes by Christian Sharaf (@sharafc) on CodePen.

display: block

A block element always starts on a new line and takes up the full width available, defaulting to 100% if the parent doesn't define otherwise. There are a lot of elements which are by default a block element (having the display: block property):

<address> <article> <aside> <blockquote> <canvas> <dd> <div> <dl> <dt>
<fieldset> <figcaption> <figure> <footer> <form> <h1>-<h6> <header>
<hr> <li> <main> <nav> <noscript> <ol> <p> <pre> <section> <ul> <video>

display: table

display: table is a bit of a speciality. Like display: block it creates a block formating context, but due to the nested markup it behaves more like a display: inline-block and its children open their own block contexts. For a detailed look, please check the official W3 documentation for tables or have a look at the extensive article about tables from Senktech.

display: inline

An inline element only takes the width and height its content needs and does not force a new line. Styling margin and padding will only affect the width, but not the height of the element since it doesn’t impact the page layout. By default inline elements can not contain block elements. Following a list of some elements which are by default display: inline:

<a> <abbr> <acronym> <b> <big> <br> <button> <cite> <code> <em> <i> <img> <input> <label> <map>
<object> <output> <script> <select> <small> <span> <strong> <sub> <sup> <textarea>

display: inline-block

Now comes a more specific display property, which is not defaulted by any of the common HTML elements. The behaviour is the same like an inline element with the addition that it can take width and height and respects margins and paddings. It still does not force a new line or defaults to the full width of the parent. It just influences its own layout. This can be helpful if you want to have a link which should be a bit more prominent (call-to-action) or want to have a horizontal navigation.

display: flow-root

As (maybe) a not so known display property, it really shines when you are working with lots of floats and have to use the famous clearfix hack. Fear no more! With display: flow-root there is no need for this anymore. An element with display: flow-root generates a block container and always establishes a new block formatting context for its contents. Therefore it clears all surrounding floats for its generated container. Also it is widely supported (IE11 not included) and can really easy up your CSS code base.

Further reading:

display: flex

display: flex creates a Flexbox container, a one-dimensional (either row or column) layout model. It offers the possibility to easily distribute space between items, change flow-directions and growing of content.

Further reading:

display: grid

display: grid creates a Grid container that holds all the elements of a CSS Grid you define. A CSS Grid enables you to seperate source (HTML) and layout (CSS) and redefine the layout, e.g. with Media Queries, by just reordering the items in your grid. In difference to a Flexbox Layout, a Grid Layout is 2-dimensional (consists of rows AND columns).

Further reading:


Both layout types (Flexbox and Grid) are a bit more complex and deserve their own posts. Since both are now widely supported (even IE11 supports a subset) you have powerful layout mechanism at your disposal, way beyond layout tables and div soups. So stay tuned.