Primary Navigation Location: Built in Flexibility

When I’m working with a starter theme or on a project with flexible parameters, I want a lot of flexibility. Some projects need as much room as possible for the primary navigation, some don’t. Some projects need a widget area in the site header, some don’t. I have two pet peeves with how I see things working in some WordPress themes:

  1. if there is no widget in the site header area, there is just a big empty space instead, because generally the logo is still fairly small. So either the logo is still on the left and the empty space is giant, or the logo is centered, and the empty space is still giant, but doesn’t feel as bad because it’s divided up more evenly.
  2. a lot of themes seem to suggest that the right answer is to use the header right widget area for the primary navigation, so that you use your space efficiently. I consider this problematic, because I think it’s better, for multiple reasons, to use a registered menu location for menus, and menus in widgets only sparingly.

Mostly, I feel like a starter theme needs to be as flexible as possible, and I want to know that things will lay out well, regardless of whether I’m setting my theme up to look like the demo.

I’m talking primarily about child themes for the Genesis Framework (affiliate link), and this is a Genesis specific tutorial, so if you’re not using Genesis, I suggest you fix that and then come back.

Here’s how I’ve solved that in my own starter theme: if there is a widget in the header right widget area, the primary navigation goes in its normal location, below the site header element:

Primary Navigation in Default Location

If there is no widget active, the theme evaluates that and places the navigation in the site header element instead:

Primary Navigation With No Header Right Widget

The great thing is that Genesis makes this process pretty easy. I get a lot of the work done quickly in my theme’s functions.php file:

add_action( 'genesis_before_header', 'leaven_maybe_move_primary_nav' );
 * Maybe move the primary navigation to the header (if no widget in header-right).
function leaven_maybe_move_primary_nav() {
	if ( is_active_sidebar( 'header-right' ) ) {
	remove_action( 'genesis_after_header', 'genesis_do_nav' );
	add_action( 'genesis_header', 'genesis_do_nav', 11 );
}Code language: JavaScript (javascript)

I can do this all in one function. I just check if the header-right widget area is active. If it is, I quit early and let Genesis do everything it normally does. If it isn’t, though, I remove the normal primary navigation call from the genesis_after_header hook and add it to the genesis_header hook instead, with a priority of 11, which places it between the title area (10) and the header closing markup (15).

The rest of the work is all CSS, and can be pretty subjective. Genesis makes this easy, because if your theme does not use the header right widget area, a new body class, .header-full-width, is automatically added to your site. (So, if you style things well, and have a widget which is only in the header right widget area on certain pages, your theme will follow right along, quite easily.)

You can see from the screen shots above that I use a different logo image, and the site header and primary navigation have different background colors in each case. The text alignment on the navigation also changes from centered to right if the widget area is inactive. I think the most important, and most opinionated (meaning it may not be right for you), part of what I’ve done in my theme is that if the widget area is not active, I use flexbox styling to make everything line up nicely in the site header. Here’s the high points of my theme styling (for the full width header), without the colors and logo images:

/* ## Full Width Header
----------------------------------------- */
.header-full-width .title-area {
	-webkit-box-flex: 1;
	-webkit-flex-grow: 1;
	-ms-flex-positive: 1;
	flex-grow: 1;

.header-full-width .nav-primary {
	background-color: transparent;
	-webkit-box-flex: 1;
	-webkit-flex-grow: 1;
	-ms-flex-positive: 1;
	flex-grow: 1;
	max-height: 76px;
	z-index: 100;

.header-full-width .nav-primary .menu-item:last-of-type > a {
	padding-right: 0;

.header-full-width .nav-primary .genesis-nav-menu {
	text-align: right;

.header-full-width .nav-primary .genesis-nav-menu .menu-item:hover .sub-menu .sub-menu {
	margin: -55px 0;
	left: -199px;

.header-full-width .site-header {
  background-color: #292929;
	background-color: rgba(41, 41, 41, 0.9);
	width: 100%;
	z-index: 800;

.header-full-width .site-header > .wrap {
	display: -webkit-box;
	display: -webkit-flex;
	display: -ms-flexbox;
	display: flex;
	-webkit-box-pack: justify;
	-webkit-justify-content: space-between;
	-ms-flex-pack: justify;
	justify-content: space-between;
	padding: 0;

.header-full-width .site-title a,
.header-full-width .site-title a:hover,
.header-full-width .site-description {
	color: #fff;

.header-full-width.header-image .title-area {
	padding: 0;

/* ## Widget Area
--------------------------------------------- */
.site-header .widget-area {
	-webkit-box-ordinal-group: 4;
	-webkit-order: 3;
	-ms-flex-order: 3;
	order: 3;
	width: 100%;
}Code language: CSS (css)

There is likely more to the styling than just that, but it is going to depend on your theme and preferences. For example, you may not want the dark site header with the white logo.

Want to see it in action? Visit this demo site–the posts page has a widget in the header right widget area; the rest of the site does not. Feel free to use Firebug or Chrome’s Dev Tools to look at the CSS and use what you like.

Reader Interactions

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.