Skip to main content

AtoZ CSS Screencast: The CSS Display Property

By Guy Routledge



Free JavaScript Book!

Write powerful, clean and maintainable JavaScript.

RRP $11.95

Loading the player…

This article is a part of our AtoZ CSS Series. You can find other entries to the series here.


How elements take up space on the page is controlled by their display.

There used to be two broad display types in CSS: elements were inline or block-level.

Block vs. Inline

Block elements start on a new line and fill the width of their parent container. We saw this behavior in “Episode 1: auto” when we looked at auto dimensions.

inline elements remain in a line and only take up the width of their contents.


In HTML5, elements are categorized differently, the broadest categories being “flow content” and “phrasing content”. There are further categories for embedded content, interactive content and form associated content but there’s a lot of cross-overs between these different categories.

Here’s a list of flow content elements. Elements like <div>, <article>, <section> and <form> are block-like elements which often contain many other child elements. But this list also contains <a>, <em>, <span> and <input> which are inline elements – often found in running text where it would be undesirable for them to start on a new line.

The list of phrasing content elements doesn’t contain a lot of the block-like elements from flow content, but it does include things like <em>, <span> and <input> which were also in the previous list.

It turns out there is no clear mapping of block to flow content and inline to phrasing content so we better look elsewhere.

First, it’s worth noting that in HTML, all elements are inline by default and their display characteristics are largely determined by the user agent stylesheet, or set by us when we write CSS.

If we look through the user agent stylesheet of Chrome, we find the following list of elements that have their display property set to block. There are a few oldies in here too for backward compatibility.

So, if there are 44 block elements in Chrome and all HTML elements are inline by default, the rest must be inline, right?

Well, not exactly, as there are more values for display than just inline and block.

We have display:none for hiding things. There’s also inline-block, table, inline-table, table-cell, table-column, table-column-group, table-footer-group, table-header-row, table-row, table-row-group, list-item, run-in, and new layout modes like flex, inline-flex, grid and inline-grid. It would take too long to look a’ all of these, so let’s take a selection of the most commonly used.


A <div> is a generic box that has display:block by default. The box is the full width of the page and as high as necessary to contain all its content. Blocks can be spaced out with margin.


In contrast, a <span> which is display:inline by default only takes up the width of its content and doesn’t respond to properties like width, height and margin. We can set the display property of this <span> to block and then all of these other properties will apply.

span {
  display: block;
  width: 50%;
  margin: 1em auto;


It’s common to want the benefits of both block and inline at the same time. Fortunately, display:inline-block has us covered.

.box {
  display: inline-block;
  width: 10%;
  margin-right: 1em;

Inline list

inline block is a great way to turn an unordered list of links into a horizontal nav. We can also apply spacing with padding and add a background color to each one if we like. One thing you’ll notice is that even though there is no margin on the items, there is a small space between them. This space can be removed by setting the font-size to zero or removing the whitespace between the tags in the markup. An alternative is to use an HTML comment to close the gap before and after each item.

If this process seems a little clunky, there’s an alternative approach using float which we’ll look at in “Episode 6”.

Table & Table-cell

Using tables used to be the way the web was built. Fortunately, that’s not the case any more. But sometimes, the way that table elements lay out are beneficial. Instead of using a table element, we can use a <div> with display:table and child elements with display:table-cell.

One of the benefits of this layout is that the table cells have equal heights – something that is otherwise difficult to achieve.

Both inline-block elements and table-cells respond to vertical alignment and we’ll be taking a deep dive into that in “Episode 22”.

Bonus Quick Tip

Not all things are equal when we don’t want to display content.

display: none is not the same as visibility: hidden

  • display: none does not allocate any space on the page; the element is removed from the normal flow and the space it once occupied is removed.
  • visibility: hidden does still take up its original space on the page; the item simply cannot be seen. This is much like setting opacity: 0.

For example, see the below CSS code:

.display-test {
  display: none;
.vis-test {
  visibility: hidden;

Accompanying the following HTML:

  <p>Lorem ipsum dolor sit amet ...</p> 
  <p class="display-test">Ut enim ad minim veniam ...</p>
  <p>Lorem ipsum dolor sit amet, consectetur ...</p> 
  <p>Lorem ipsum dolor sit amet ...</p> 
  <p class="vis-test">Ut enim ad minim veniam ...</p>
  <p>Lorem ipsum dolor sit amet, consectetur ...</p>

The .display-test text will have a rather different result to the .vis-test text, as you’ll see in the below CodePen:

See the Pen tip-d by SitePoint (@SitePoint) on CodePen.

Notice how there is blank space in the second box where a paragraph has been hidden. There is no allocated space in the first box that uses display: none.

Front-end dev and teacher at The General Assembly London. A to Z CSS Screencaster, Founder of and Co-founder of The Food Rush.

New books out now!

Get practical advice to start your career in programming!

Master complex transitions, transformations and animations in CSS!