Justifying the Site Navigation

Last Updated June 28, 2016

First, I’ll explain where we’re going:

We want a horizontal navigation system that will span the entire width of the container element. As you resize the browser window, it continues to span the entire width. Then, once the items get so close together, the menu can readjust.

Animated Justified Nav

Let’s take the following HTML:

<nav class=“nav”>
<ul>
<li><a href=“#”>Home</a></li>
<li><a href=“#”>About</a></li>
<li><a href=“#”>Blog</a></li>
<li><a href=“#”>Contact Us</a></li>
</ul>
</nav>

This looks pretty straightforward, right?

If you display this in the browser, as is, you’ll probably see something like this:

Vanilla HTML Navigation

Let’s start styling:

nav ul {
list-style: none;
margin: 0;
padding: 0;
}

All we’ve done so far is to remove the bullets and any margin and padding from the navigation list (all included by default). Now, our rendered code looks like this:

Styled HTML Navigation

NOTE:

I have a SASS starter library (I wrote about it here) I like to start projects with. In that, I actually have two includes that I would have used here, except I’m trying to keep it on the vanilla CSS side. But, thought I might include this tid bit here, regardless.

%no-margin-padding {
margin: 0;
padding: 0;
}
%no-bullets {
list-style: none;
}

This would change my nav ul definition to read:

nav ul {
@extend %no-margin-padding;
@extend %no-bullets;
}

You may look at this and think that my nav ul definition only changed one line and technically I had to write 8 additional lines of code to get everything to work. Au contraire. I’ll use those extend classes elsewhere on the site, in addition to here. In the long run, I end up saving time.

Then, we need to make sure that the list displays all in one line.

nav ul li {
		display: inline-block;
}

Display inline

Next we want the text to be justified:

nav ul {
	list-style: none;
	margin: 0;
	padding: 0;
	text-align: justify;
}

The magic happens here. We add an additional element to our DOM:

<nav class=“nav”>
		<li class=“home”><a href=“#”>Home</a></li>
		<li class=“about”><a href=“#”>About</a></li>
		<li class=“blog”><a href=“#”>Blog</a></li>
		<li class=“contact-us”><a href=“#”>Contact Us</a></li>
		<li class="stretch"></li>
</ul>

Then, add the following styles:

nav ul li.stretch {
	display: inline-block;
	width: 100%;
}

This final element, will ensure that your navigation spans the entire width of the container. Pretty neat!

See the Pen Justified Navigation by Amy Dutton (@ahaywood) on CodePen.

NOTE:

There’s actually another way to achieve the same effect, using flexbox. But, we’ll save that for another day.


If you’re using WordPress:

So, you’re developing in WordPress and want to know how you get this technique to work? It’s pretty easy, actually.

In order to display a navigation system in WordPress, you have to do several things:

  1. Register the navigation within functions.php for access within the Appearance > Menus system
  2. Use a function to display that content to the frontend.

Let’s do it!

Regstering the navigation

Within functions.php, if you don’t already have this function (or something similar), add it:

register_nav_menus(array( 
		
	// Main Navigation
   'header-menu' => 'Header Menu', 
 	
	// Footer Navigation
    'footer-menu' => 'Footer Menu'

));

We’re using a function from WordPress’s core: register_nav_menus.

We’re passing in an array.

NOTE:

If that’s already over your head, it’s OK. You can think of an array as a filing cabinet that contains a bunch of different information.

You can have a “filing cabinet of fruit”:

<?php $fruit = array('orange', 'banana', 'apples'); ?>

or boy names:

<?php $boy\_names = array('Hank', 'Isaac', 'Jake', 'Luke'); ?>

I don’t want this to throw you off, but sometimes, you may see an array written like this:

<?php $fruit = ['orange', 'banana', 'apples']; ?>

The [ ] are just shorthand. It’s the same thing.

To get to the content of our array, you do this:

<?php echo $fruit[0]; ?> 

That will return orange.

Computers are funny, and start counting at 0.

In our fruit example, orange is 0, banana 1, and apples 2. When you count the items, there are still 3 total.

Now then, if we go back to our WordPress code, you may object and say “Amy, there’s => in my code, what’s that about?!”

The technical name is that a multi dimensional array. It’s a value-key pair.

Don’t worry. I’ll break it down.

The code on the left side of the => gives us a way to easily find and reference the value. You can think of it as your file folder label.

Instead of having to reference menu array items with numbers as as we were doing before, ($fruit[0]), we can use our “label.”

Let’s keep our fruit example and give them labels. I’m going to split the code into multiple lines to make it easier to read:

<?php $fruit = array(
	'orange' => 'orange',
	'yellow' => 'banana',
	'red' => 'apple',
); ?>

Hopefully the fact that an orange is orange doesn’t throw you off. 😉

On the left, the label, we have the color and on the right we have the fruit.

You can still reference a banana as $fruit[1] but you can also reference it as $fruit['yellow']. Much better? You don’t feel as much like a robot, do you?

Now, that WordPress code is starting to make more sense and be more legible:

register_nav_menus(array( 
		
		// Main Navigation
   'header-menu' => 'Header Menu', 
 	
	// Footer Navigation
    'footer-menu' => 'Footer Menu'

));


header-menu is just a label for our Header Menu. Notice, it doesn’t have spaces in the name.

The text on the right is what displays on the Appearance > Menus page.

If you wanted to add an item, it’s pretty simple. Add a comma after the last item, give the new item a reference value and the text you want to see within WordPress:

register_nav_menus(array( 
		
		// Main Navigation
   'header-menu' => 'Header Menu', 
 	
	// Footer Navigation
    'footer-menu' => 'Footer Menu',

	// Sidebar Navigation
	'sidebar-menu' => 'Sidebar Menu'

));

Within our theme, we just have to call it. WordPress has a function for that, wp_nav_menu

wp_nav_menu(
    array(
        'theme_location'  => 'header-menu',
        'menu'            => '',
        'container'       => 'div',
        'container_class' => 'menu-{menu slug}-container',
        'container_id'    => '',
        'menu_class'      => 'menu',
        'menu_id'         => '',
        'echo'            => true,
        'fallback_cb'     => 'wp_page_menu',
        'before'          => '',
        'after'           => '',
        'link_before'     => '',
        'link_after'      => '',
        'items_wrap'      => '<ul>%3$s</ul>',
        'depth'           => 0,
        'walker'          => ''
        )
    );

Hopefully, that array thing is starting to look more familiar and not quite as scary.

The array allows us to pass in several properties.

There are only a few that we really care about.

theme_location allows us to specify which menu we want to display. Remember, we created 3: header-menu, footer-menu, and sidebar-menu.

Right now, we’re showing the header menu, but we could easily change that:

theme_location => 'footer-menu'

The container value is for whatever you want to wrap your menu with. Right now, it’s set to a div (also the default). Let’s change that to a space.

'container' => ' '

We don’t want to leave it empty because then the function will use the default value (div).

Last thing to change here:

'items_wrap'      => '<ul>%3$s</ul>',

becomes:

'items_wrap'      => '%3$s',

That weird value %3$s is what WordPress is using to reference the content within the <ul></ul>. So, we’re simply saying, still show the content of the menu (%3$s) but don’t wrap it in an <ul></ul>.

If we look at the HTML it produces, it should look something like this:

<li><a href="/home">Home</a></li>
<li><a href="/about">About</a></li>
<li><a href="/contact">Contact</a></li>

or something similar.

Within our theme file, we want to add the extra tags to make our spiffy justification nav work:

<nav>
	<ul>

	<?php wp_nav_menu(
     array(
         'theme_location'  => 'footer-menu',
         'menu'            => '',
         'container'       => ' ',
         'container_class' => 'menu-{menu slug}-container',
         'container_id'    => '',
         'menu_class'      => 'menu',
         'menu_id'         => '',
         'echo'            => true,
         'fallback_cb'     => 'wp_page_menu',
         'before'          => '',
         'after'           => '',
         'link_before'     => '',
         'link_after'      => '',
         'items_wrap'      => '%3$s',
         'depth'           => 0,
         'walker'          => ''
         )
     ); ?>

	<li class="stretch"></li>

	</ul>
</nav>

Perfect! Done and done!


All the Code

And just so it’s all in one place:

styles.css

nav ul {
	list-style: none;
	margin: 0;
	padding: 0;
	text-align: justify;
}

nav ul li.stretch {
 	display: inline-block;
 	width: 100%;
}

functions.php

register_nav_menus(array( 
		
		// Main Navigation
   'header-menu' => 'Header Menu', 
 	
	// Footer Navigation
    'footer-menu' => 'Footer Menu',

	// Sidebar Navigation
	'sidebar-menu' => 'Sidebar Menu'

));

WordPress Theme File

<nav>
	<ul>

	<?php wp_nav_menu(
     array(
         'theme_location'  => 'footer-menu',
         'menu'            => '',
         'container'       => ' ',
         'container_class' => 'menu-{menu slug}-container',
         'container_id'    => '',
         'menu_class'      => 'menu',
         'menu_id'         => '',
         'echo'            => true,
         'fallback_cb'     => 'wp_page_menu',
         'before'          => '',
         'after'           => '',
         'link_before'     => '',
         'link_after'      => '',
         'items_wrap'      => '%3$s',
         'depth'           => 0,
         'walker'          => ''
         )
     ); ?>

	<li class="stretch"></li>

	</ul>
</nav>

The Conversation