All Collections
Website
Theming
Tweak a stock theme or page template
How to make a multi-level top nav dropdown menu
How to make a multi-level top nav dropdown menu

In NationBuilder's public themes, the top nav dropdown menus are one level deep. But, you can create one two levels deep with some tweaking.

Updated over a week ago

The navigation structure can be found in the _nav.html partial template in your custom theme's Templates section. In Aware, _nav.html contains the following nav structure:

<nav id="menu" role="navigation">
<ul id="topnav" class="topnav desktop-nav">
{% for child in site.root_nav_pages %}
{% if child.leaf? or child.nav_children.size == 0 %}
<li {% if child.is_or_is_ancestor_of_current_page? %}class="active"{% endif %}>
<a href="{{ child.url }}">{{ child.name }}</a>
</li>
{% else %}
<li class="{% if child.is_or_is_ancestor_of_current_page? %}active{% endif %} drop">
<a href="{{ child.url }}">{{ child.name }} <i class="icon-angle-down"></i></a>
<ul class="sub">
{% if site.show_parent_in_nav_dropdown? %}
<li class="show-parent"><a href="{{ child.url }}">{{ child.name }}</a></li>
{% else %}
<li class="show-parent mobile-visible"><a href="{{ child.url }}">{{ child.name }}</a></li>
{% endif %}
{% for child2 in child.nav_children %}
<li><a href="{{ child2.url }}">{{ child2.name }}</a></li>
{% endfor %}
</ul>
</li>
{% endif %}
{% endfor %}
</ul>
</nav>

📌 Note: The unordered list with the "sub" class – this is the first (and only) dropdown level. Via liquid, the "sub" element shows the parent element if the "show parent" option is turned on in the control panel, and also loops through and outputs its children via the "nav_children" attribute. We'll be using the "nav_children" attribute again to print the second dropdown level:

<nav id="menu" role="navigation">
<ul id="topnav" class="topnav desktop-nav">
{% for child in site.root_nav_pages %}
{% if child.leaf? or child.nav_children.size == 0 %}
<li {% if child.is_or_is_ancestor_of_current_page? %}class="active"{% endif %}>
<a href="{{ child.url }}">{{ child.name }}</a>
</li>
{% else %}
<li class="{% if child.is_or_is_ancestor_of_current_page? %}active{% endif %} drop">
<a href="{{ child.url }}">{{ child.name }} <i class="icon-angle-down"></i></a>
<ul class="sub">
{% if site.show_parent_in_nav_dropdown? %}
<li class="show-parent"><a href="{{ child.url }}">{{ child.name }}</a></li>
{% else %}
<li class="show-parent mobile-visible"><a href="{{ child.url }}">{{ child.name }}</a></li>
{% endif %}
{% for child2 in child.nav_children %}
{% if child2.nav_children.size > 0 %}
<li class="drop">
<a href="{{ child2.url }}">{{ child2.name }}<i class="icon-right-open"></i></a>
<ul class="subsub">
{% for child2child in child2.nav_children %}
<li>
<a href="{{ child2child.url }}">{{ child2child.name }}</a>
</li>
{% endfor %}
</ul>
</li>
{% else %}
<li>
<a href="{{ child2.url }}">{{ child2.name }}</a>
</li>
{% endif %}
{% endfor %}
</ul>
</li>
{% endif %}
{% endfor %}
</ul>
</nav>

Within the "sub" dropdown menu, we've now added a "subsub" element to the links in this dropdown that contain at least one "nav_children". This block loops through and outputs the links of the children pages of the first dropdown's links (in other words, the "nav_children" of the "nav_children"). Parent links that contain children also have a "drop" class added to them.

So, we now have the contents of the second level dropdowns, but we still need to style these menus and hide them until their parents are hovered over. Dropdowns should default to the hidden state, and since we know that parents containing children also have a "drop" class, we can design our stylesheet to show the children of a link with the "drop" class when it's hovered over. The following snippet, when placed in your tablet-and-desktop.scss stylesheet, will style these dropdowns for the Aware theme:

.subsub {
position: absolute;
width: 200px;
left: 200px;
padding-top: 10px;
margin-top: -38px;
background-color: $theme-color-3;
display:none;
@include border-radius(0 2px 2px 2px);
}
 
li.drop:hover > .subsub {
display: block;
}
Did this answer your question?