amy-d
3/21/2017 - 12:54 PM

WordPress: Mega Menu

WordPress: Mega Menu

<!-- NAV BAR -->
    <div class="primary-menu__wrapper">
        <div class="primary-menu">
            <nav class="nav" role="navigation">
                <ul>
                <?php $locations = get_nav_menu_locations();

                // if there's a location for the primary menu
                if ( isset( $locations['primary-menu']) ) {
                    $menu = get_term( $locations['primary-menu'], 'nav_menu');

                    // if there are items in the primary menu
                    if ( $items = wp_get_nav_menu_items( $menu->name ) ) {

                        // loop through all menu items to display their content
                        foreach ( $items as $item ) {

                            // if the current item is not a top level item, skip it
                            if ($item->menu_item_parent != 0) {
                                continue;
                            }

                            // get the ID of the current nav item
                            $curNavItemID = $item->ID;

                            // get the custom classes for the item
                            // (determined within the WordPress Appearance > Menu section)
                            $classList = implode(" ", $item->classes);
                            echo "<li class=\"{$classList}\">";
                            echo "<a href=\"{$item->url}\">{$item->title}</a>";

                            // build the mega-menu
                            // if 'mega-menu'  exists within the class
                            if ( in_array('has-mega-menu', $item->classes)) { ?>
                                <div class="mega-menu__wrapper js-mega-menu">
                                    <div class="mega-menu">

                                        <div class="mega-menu__content">
                                            <h2><?= $item->post_title; ?></h2>
                                            <p><?= $item->description; ?></p>
                                            <a href="<?= $item->url; ?>" class="learn-more">Learn More</a>
                                        </div>

                                        <div class="mega-menu__subnav">
                                            <nav>
                                                <ul class="subnav">
                                                <?php // cycle through the menu items and get the subnav
                                                foreach ( $items as $subnav) {
                                                    if ( $subnav->menu_item_parent == $curNavItemID) {
                                                        echo "<li><a href=\"{$subnav->url}\">{$subnav->title}</a>";
                                                    }
                                                } ?>
                                                </ul>
                                            </nav>
                                        </div>


                                    </div>
                                </div>
                            <?php }

                            // if this is the search bar
                            if ( in_array('nav-search', $item->classes) ) { ?>
                                <div class="search-bar__wrapper">
                                    <div class="search-bar">
                                        <div class="search-bar__form">
                                            <form>
                                                <input type="text" name="s" placeholder="Keywords" />
                                                <button type="button" role="submit" name="Search">Search</button>
                                            </form>
                                            <a href="#" class="js-close-search search-bar__close"><svg role="img" class="icon"><use xlink:href="<?php bloginfo('template_url'); ?>/assets/dist/img/svg.svg#close"></use></svg></a>
                                        </div> <!-- /.search-bar__form -->
                                    </div><!-- /.search-bar -->
                                </div><!-- /.search-bar__wrapper -->
                            <?php }
                            echo '</li>';

                        }
                    }
                } ?>
                </ul>
                <?php //nationsu_primary_nav(); ?>
            </nav>
        </div><!-- /.primary-menu -->
    </div> <!-- /.primary-menu__wrapper -->

I've written a massive blog post explaining this code.

A few things that are included in this gist, that might not be immediately obvious and will prevent this code from being a simple copy and paste

Within the .scss,

  • There are a few references to the Susy grid.
  • I've also referenced a few of my Sass go to mixins and extends. I've written a post about these, too.
  • There are a few references to color variables, I reference in a separate _theme.scss file.

Within WordPress

There's quite a bit of setup required in WordPress, in order for this code to work. Again, this is explained within the blog post.

/*------------------------------------*\
    #PRIMARY-MENU
\*------------------------------------*/
.primary-menu {
	@include grid;
	@include sans-serif;
	font-weight: $bold;
	height: $nav-bar-height;

	&__wrapper {
		@include clearfix();
		background: rgba(white, 0.3);
	}

	/* more explicit here to prevent conflicts with
		the megamenu / subnav */
	> .nav > ul {
		@include no-margin-padding();
		@include no-bullets();
		display: flex;
		flex-direction: row;
		justify-content: space-between;

		> li {
			border-top: 2px solid transparent;

			&:hover {
				background: white;
				border-top: 2px solid $dark-slate-blue;

				/* show mega menu on rollover */
				.mega-menu__wrapper {
					display: block;
				}
			}

			> a {
				box-sizing: border-box;
				color: $dark-slate-blue;
				display: block;
				letter-spacing: 1px;
				line-height: 40px;
				padding: 10px 35px;
				text-decoration: none;
				text-transform: uppercase;
			}

		}
	}

	.sub-menu {
		display: none;
	}
}


/* home */
.nav-home a {
	@include remove-text;
	background: path('icon-home.svg') center center no-repeat;

	&:hover {
		background: white path('icon-home.svg') center center no-repeat;
	}
}

/* search - needs to be specific in order to prevent
	interferences with the search bar */
.nav-search > a {
	@include remove-text;
	background: path('icon-search.svg') center center no-repeat;
	left: 0;
	position: relative;
	transition: left 0.5s ease-in-out;

	&:hover {
		background: white path('icon-search.svg') center center no-repeat;
	}
}





/*------------------------------------*\
    #MEGA-MENU
\*------------------------------------*/
@keyframes reveal-mega-menu {
	0% {
		height: 0%;
	}

	100% {
		height: auto;
	}
}

@keyframes fadein-mega-menu {
	0% {
		opacity: 0;
		top: -5px;
	}

	100% {
		opacity: 1;
		top: 0;
	}
}

.mega-menu {
	@include grid;
	animation: fadein-mega-menu .5s ease-in-out;
	position: relative;

	&__wrapper {
		animation: reveal-mega-menu .25s ease-in-out;
		background: white;
		box-shadow: 0 4px 4px -2px #777;
		display: none;
		left: 0;
		min-height: 320px;
		padding: 35px 0 45px;
		position: absolute;
		width: 100%;
		z-index: map-get($zindex, mega-menu);
	}

	/* content within the mega menu */
	&__content {
		@include push(1);
		@include span(7);
		box-sizing: border-box;
		border-right: 10px solid $butterscotch;
		padding-left: 33px;
		padding-right: 120px;

		/* mega menu title */
		h2 {
			@include sans-serif($light);
			font-size: em(28px);
			color: $dark-slate-blue;
			letter-spacing: 1px;
			margin-bottom: 10px;
			margin-top: 25px;
		}

		/* description */
		p {
			@include serif;
			font-size: em(18px);
			font-weight: normal;
			line-height: em(28px, 18px);
			margin-bottom: 30px;
		}

		/* learn more button */
		.learn-more {
			@include btn--inverse($dark-slate-blue, $dark-slate-blue, white);
			margin-bottom: 25px;

			&:after {
                @include btn-arrow($dark-slate-blue);
            }

            &:hover:after {
                @include btn-arrow(white);
            }
		}
	}

	/* subnavigation within the mega menu */
	&__subnav {
		@include span(4);
		@include last;

		.subnav {
			@include no-bullets;
			padding: 0;
			margin: 25px 0 25px 40px;

			li {
				font-size: em(16px);
				line-height: em(20px, 16px);
				margin-bottom: 20px;

				a {
					color: $dark-slate-blue;
					text-decoration: none;
					text-transform: uppercase;

					&:hover {
						color: $butterscotch;
					}
				}
			}
		}
	}
}