Contents

Turn children into siblings of a flex or grid parent

When making a flex or grid, you may want to assemble some children into logical groups for styling or scripting. But when doing so, it may be tricky to keep the parent layout. You may even need to turn those groups into sub flex or grid boxes, complicating the layout you’re trying to accomplish.

That’s when display: contents is useful.

When using that directive, the element’s box model is ignored, and its children are made part of the parent’s box model.

Making a nav bar with display: contents

Let’s say we have this markup for a nav bar with three sections, the site menu, the search form, and the user menu:

<nav>
	<ul class="site-menu">
		<li><a href="/">Home</a></li>
		<li><a href="/shop/">Shop</a></li>
		<li><a href="/blog/">Blog</a></li>
		<li><a href="/about/">About</a></li>
	</ul>
	<form class="search-form" action="/search/" method="post">
		<input placeholder="Search" type="search" />
	</form>
	<ul class="user-menu">
		<li><a href="/settings/">Settings</a></li>
		<li><a href="/account/">Account</a></li>
		<li><a href="/logout">Log Out</a></li>
	</ul>
</nav>

To make the <nav> a flexible box, you’d have to make it display: flex, then every section would need to be display: flex as well. That can get messy.

Instead, you can simply set display: sections on every section, making every container “invisible,” and set every child as a part of the parent display: flex:

nav {
	/* Make nav a flex box. */
	display: flex;
	flex-flow: row nowrap;
}

form,
ul {
	/* Make children part of the parent box model. */
	display: contents;

	/* Some block styling is ignored with `display: contents`. */
	background: pink;
	border: solid 1px cyan;
	flex: 0 0;
}

input {
	/* Flex and grid properties set on children are applied. */
	flex: 1 1;
}

With the above, we can easily make the flex nav bar below, yet have logical groups you can style or script to your needs later:

Nav bar with three sections—site menu, search form, and user menu—blended in the same flex box using display: contents;.

A few things to keep in mind

There are a few points you may want to consider when using display: contents:

  • Works in parent boxes using a flex (display: flex) or grid (display: grid) layout model.
  • Box styling—including background, borders, sizes—on elements in a display: contents are ignored. But inline styling—font size and text colour, for example—are still applied.
  • Flex and grid properties set on display: contents elements are ignored; only those set on their children are applied.

Another note, unlike align-content: center, display: contents uses the noun in plural. This little grammar detail can be tricky to remember, even for native speakers of English. As this article explains the difference, it’s likely because the content of align-content is uncountable as it is for the ideas—or the sum of HTML elements—contained in a piece of writing, while the contents of display: contents is plural for a list of parts—or single elements.

Demo

This demo on CodePen shows you the example nav bar using display: contents;.

👋 Hi! I'm Rem, a Web developer since 1998, in Japan since 2006. I'm the author of dress.css and Scrollerful. As you can imagine, my experience is varied, including the early days of the Web being a webmaster writing HTML files and scripts in Perl, saved on floppy disks using Notepad, to now being a tech lead for a team, writing CSS with Tailwind or JavaScript for both the backend and frontend in Neovim. I love photography, typography, and colour theory. Strangely enough, my love for print graphic design was what got me into web development. So, yes, I have a few stories to tell and tips to give, and I'm writing some of them, sometimes, here, on RÉMINO Bits.