Menu with Search
JSThis component requires JavaScript.
An alternative version of the menu that includes site search.
For more information on usage, implementation and accessibility, please visit the Menu page.
Example
<div class="bux-menu-wrapper">
<div
class="bux-container bux-grid bux-container__menu bux-container__menu--with-search"
>
<nav
id="bux-main-menu"
aria-label="Main"
class="disclosure-nav disclosure-nav-orientation-horizontal"
>
<ul class="bux-menu">
<li class="bux-menu__item">
<a
href="#"
class="bux-menu__link bux-menu__link--active disclosure-nav-item-with-submenu"
data-button-aria-label="More Level 1 Link Items"
>
Level 1 Link
</a>
<ul class="disclosure-nav-submenu disclosure-nav-submenu-closed">
<li class="bux-menu__item">
<a
href="#"
class="bux-menu__link bux-menu__link--active disclosure-nav-item-with-submenu mobile-depth-cutoff"
data-button-aria-label="More Stuff"
>
Level 2 Link
</a>
<ul
class="disclosure-nav-submenu disclosure-nav-submenu-closed mobile-visible"
>
<li class="bux-menu__item">
<a
href="#"
class="bux-menu__link bux-menu__link--active disclosure-nav-item-with-submenu"
data-button-aria-label="More Stuff"
>
Level 3 Link
</a>
<ul
class="disclosure-nav-submenu disclosure-nav-submenu-closed"
>
<li class="bux-menu__item">
<a
href="#"
class="bux-menu__link disclosure-nav-item-with-submenu"
data-button-aria-label="More Stuff"
>
Level 4 Link
</a>
<ul
class="disclosure-nav-submenu disclosure-nav-submenu-closed"
>
<li class="bux-menu__item">
<a
href="#"
class="bux-menu__link"
data-button-aria-label="More Stuff"
>
Level 5 Link
</a>
</li>
<li class="bux-menu__item">
<a
href="#"
class="bux-menu__link"
data-button-aria-label="More Stuff"
>
Level 5 Link
</a>
</li>
</ul>
</li>
<li class="bux-menu__item">
<a
href="#"
class="bux-menu__link"
data-button-aria-label="More Stuff"
>
Level 4 Link
</a>
</li>
</ul>
</li>
<li class="bux-menu__item">
<a
href="#"
class="bux-menu__link"
data-button-aria-label="More Stuff"
>
Level 3 Link
</a>
</li>
</ul>
</li>
<li class="bux-menu__item">
<a
href="#"
class="bux-menu__link"
data-button-aria-label="More Stuff"
>
Level 2 Link
</a>
</li>
<li class="bux-menu__item">
<a
href="#"
class="bux-menu__link"
data-button-aria-label="More Stuff"
>
Level 2 Link
</a>
</li>
<li class="bux-menu__item">
<a
href="#"
class="bux-menu__link"
data-button-aria-label="More Stuff"
>
Level 2 Link
</a>
</li>
</ul>
</li>
<li class="bux-menu__item">
<a
href="#"
class="bux-menu__link disclosure-nav-item-with-submenu"
data-button-aria-label="More Stuff"
>
Level 1 Link
</a>
<ul class="disclosure-nav-submenu disclosure-nav-submenu-closed">
<li class="bux-menu__item">
<a
href="#"
class="bux-menu__link"
data-button-aria-label="More Stuff"
>
Level 2 Link
</a>
</li>
<li class="bux-menu__item">
<a
href="#"
class="bux-menu__link"
data-button-aria-label="More Stuff"
>
Level 2 Link
</a>
</li>
<li class="bux-menu__item">
<a
href="#"
class="bux-menu__link"
data-button-aria-label="More Stuff"
>
Level 2 Link
</a>
</li>
<li class="bux-menu__item">
<a
href="#"
class="bux-menu__link"
data-button-aria-label="More Stuff"
>
Level 2 Link
</a>
</li>
</ul>
</li>
<li class="bux-menu__item">
<a
href="#"
class="bux-menu__link"
data-button-aria-label="More Stuff"
>
Level 1 Link
</a>
</li>
<li class="bux-menu__item">
<a
href="#"
class="bux-menu__link disclosure-nav-item-with-submenu"
data-button-aria-label="More Stuff"
>
Level 1 Link
</a>
<ul class="disclosure-nav-submenu disclosure-nav-submenu-closed">
<li class="bux-menu__item">
<a
href="#"
class="bux-menu__link"
data-button-aria-label="More Stuff"
>
Level 2 Link
</a>
</li>
<li class="bux-menu__item">
<a
href="#"
class="bux-menu__link"
data-button-aria-label="More Stuff"
>
Level 2 Link
</a>
</li>
<li class="bux-menu__item">
<a
href="#"
class="bux-menu__link"
data-button-aria-label="More Stuff"
>
Level 2 Link
</a>
</li>
<li class="bux-menu__item">
<a
href="#"
class="bux-menu__link"
data-button-aria-label="More Stuff"
>
Level 2 Link
</a>
</li>
</ul>
</li>
<li class="bux-menu__item">
<a
href="#"
class="bux-menu__link"
data-button-aria-label="More Stuff"
>
Level 1 Link
</a>
</li>
</ul>
</nav>
<div class="bux-menu__search">
<div
class="bux-form__text-field--menu-search__wrapper"
role="dialog"
aria-modal="true"
>
<form id="site-search" class="bux-search" role="search">
<label class="bux-search__label visually-hidden" for="buxSearch"
>Search</label
>
<input
id="buxSearch"
class="bux-search__input bux-form__text-field bux-from__text-field--menu-search"
placeholder="Search"
tabindex="-1"
/>
<button class="bux-search__submit is-hidden" tabindex="-1">
<span class="visually-hidden">Submit search</span>
</button>
</form>
</div>
<button
id="menuSearchBtn"
type="button"
aria-expanded="false"
aria-controls="site-search"
>
<span class="visually-hidden">Toggle search dialog</span>
<span
id="searchIcon"
class="icon icon-search"
aria-hidden="true"
></span>
</button>
</div>
</div>
</div>
{#
Buckeye UX - version 1.3.4
Copyright (C) 2026 The Ohio State University
#}
{#
Menu Component
Available Variables:
- modifier: Menu variant (null or "with-search")
- nav_id: Unique identifier for the menu
- aria_label: Aria label for the menu
- mobileDepthCutoff: Boolean. Hide deep menu levels on desktop
- items: Array of menu items
- item.title: Item title
- item.url: Item URL
- item.active: Boolean. True if active
- item.aria_label: Aria label for the disclosureNav generated button
- item.subitems: Array of submenu items
If using the search variant:
- label: Set to "with-search"
- inputId: Unique ID for the search input
- searchFormId: Unique ID for the search form
#}
{# ===================================================
Macros
==================================================== #}
{% macro link(item, depth, mobileDepthCutoff) %}
{% set linkClasses = ['bux-menu__link'] %}
{% if item.active %}
{% set linkClasses = linkClasses|merge(['bux-menu__link--active']) %}
{% endif %}
{% if item.subitems %}
{% set linkClasses = linkClasses|merge(['disclosure-nav-item-with-submenu']) %}
{% endif %}
{% if item.subitems and mobileDepthCutoff and depth == 1 %}
{% set linkClasses = linkClasses|merge(['mobile-depth-cutoff']) %}
{% endif %}
<a href="{{ item.url }}"
class="{{ linkClasses|join(' ') }}"
{% if item.aria_label %}data-button-aria-label="{{ item.aria_label }}"{% endif %}>
{{ item.title }}
</a>
{% endmacro %}
{% macro submenu(items, depth, mobileDepthCutoff) %}
{% import _self as menu %}
{% if items %}
{% set submenuClasses = ['disclosure-nav-submenu', 'disclosure-nav-submenu-closed'] %}
{% if mobileDepthCutoff and depth == 2 %}
{% set submenuClasses = submenuClasses|merge(['mobile-visible']) %}
{% endif %}
<ul class="{{ submenuClasses|join(' ') }}">
{% for item in items %}
<li class="bux-menu__item">
{{ menu.link(item, depth, mobileDepthCutoff) }}
{% if item.subitems %}
{{ menu.submenu(item.subitems, depth + 1, mobileDepthCutoff) }}
{% endif %}
</li>
{% endfor %}
</ul>
{% endif %}
{% endmacro %}
{# ===================================================
Markup
==================================================== #}
{% import _self as menu %}
<div class="bux-menu-wrapper">
<div class="bux-container bux-grid bux-container__menu {% if modifier %}bux-container__menu--{{ modifier }} {% endif %}">
<nav id="{{ nav_id }}" aria-label="{{ aria_label }}" class="disclosure-nav disclosure-nav-orientation-horizontal">
{% if items %}
<ul class="bux-menu">
{% for item in items %}
<li class="bux-menu__item">
{{ menu.link(item, 0, mobileDepthCutoff) }}
{% if item.subitems %}
{{ menu.submenu(item.subitems, 1, mobileDepthCutoff) }}
{% endif %}
</li>
{% endfor %}
</ul>
{% endif %}
</nav>
{% if label == 'with-search' %}
<div class="bux-menu__search">
<div class="bux-form__text-field--menu-search__wrapper" role="dialog" aria-modal="true">
<form id="{{ searchFormId }}" class="bux-search" role="search">
<label class="bux-search__label visually-hidden" for="{{ inputId }}">Search</label>
<input id="{{ inputId }}" class="bux-search__input bux-form__text-field bux-from__text-field--menu-search" placeholder="Search" tabindex="-1" />
<button class="bux-search__submit is-hidden" tabindex="-1">
<span class="visually-hidden">Submit search</span>
</button>
</form>
</div>
<button id="menuSearchBtn" type="button" aria-expanded="false" aria-controls="{{ searchFormId }}">
<span class="visually-hidden">Toggle search dialog</span>
<span id="searchIcon" class="icon icon-search" aria-hidden="true"></span>
</button>
</div>
{% endif %}
</div>
</div>
Implementation Notes
By default, mobileDepthCutoff is set to true, which hides links of a depth
greater than two in the menu tree on large viewports. This is meant to overlap
with the Sidebar Navigation which by default is
hidden on smaller viewports.
References
- BUX Design Principle: Design Elements