Very frequently horizontal site navigational elements are required to “stretch” with browser size changes. While flexbox can be used to achieve this kind of layout, and does boast some advantages in doing so, there’s another, frequently overlooked option that employs less code and has far greater cross-browser compatibility.

I’ll explore both possibilities, using navigation for the fictional Snap-Tite Rubber Company as an example. The base HTML will be the same in both cases:

<header>
	<h1>Snap-Tite Rubber Co.</h1>
	<nav>
		<a href="#">Home</a>
		<a href="#">About</a>
		<a href="#">Basic Services</a>
		<a href="#">Specialty Services</a>
		<a href="#">Contact Us</a>
	</nav>
</header>

There’s also CSS that’s shared in both solutions:

header {
	background-image: url(light_toast.png);
	text-transform: uppercase;
	text-align: center;
}
h1 { 
	font: 4rem "Bree Serif";
	text-shadow: -1px -1px 1px rgba(255,255,255,0.4),
		1px 1px 1px rgba(0,0,0,0.4);
	color: rgba(255,255,255,0.6);
	padding-top: 1rem;
	opacity: 0.3;
	line-height: 1;
	margin: 1.5rem;
}
header nav { 
	font-weight: 100; 
	font-family: Agenda-Light, Agenda, Arial, sans-serif; 
}
header nav a { 
	text-decoration: none; 
	font-size: 1.4rem;
	color: #333;
	background: rgba(255,255,255,0.4);
	transition: .6s;
	padding: .5rem;
}
header nav a:list-child {
	border-right: none;
}
header nav a:hover {
	background: rgba(0,0,0,0.5);
	color: #fee;
}

The rest of the CSS is unique to one solution or another.

Option 1: display: table-cell layout

The easiest way to create stretchy navigation is to use display: table and related values. I’m assuming for this example that the design also calls for the links to be vertically aligned on their centers:

header nav {
	display: table;
	width: 100%;
}
header nav a {
	display: table-cell;
	vertical-align: middle;
}

At this point, you are relying on the content of each link to determine its width. Alternatively, you could evenly divide the table cell by using table-layout: fixed:

header nav {
	display: table;
	width: 100%;
	table-layout: fixed;
}

Naturally, we also need to cover requirements. The obvious solution is to arrange the links vertically when they start to cram too close together:

@media (max-width: 700px) { 
	header nav a {
		display: table-row;
		width: 100%;
	}
}

The major advantages of this solution are:

  • The syntax is relatively easy
  • The solution works all the way back to IE8

An alternative, and more recent, solution to create stretchy navigation is to use .

Option2: Flexbox layout

While flexbox would seem to be the ideal solution, it actually requires significantly more code, even without taking vendor prefixes and previous syntaxes of the spec into account:

header nav {
	display: flex;
}
header nav a { 
	flex: 1 1 auto;
	display: flex;
	align-items: center;
	justify-content: center;
}

However, the responsive design solution is very similar:

@media (max-width: 700px) { 
	header nav { 
		flex-direction: column;
	}
}

The links themselves need to be display: flex in order to vertically align their content with align-items: center, and flex: 1 1 auto; so that they stretch vertically as well as horizontally. Despite its verbosity, the method does provide more options in the distribution of links, by using space-around or space-between in the justify-content property for the nav element.

Both approaches have their advantages and disadvantages. It’s entirely possible to use display: table as a fallback solution for a flexbox approach, as the two often achieve similar design goals.

Enjoy this piece? I invite you to follow me at twitter.com/dudleystorey to learn more.