Skip to main content
Horizon’s navigation system features rich mega menus with support for images, featured products, featured collections, and multi-level navigation.

Desktop Menu

On desktop (≥750px), the header displays a horizontal mega menu:
<header-menu class="header-menu" data-hydration-key="header-menu">
  <nav class="menu-list" aria-label="{{ 'accessibility.header_navigation_label' | t }}">
    {% render 'overflow-list',
      class: 'overflow-menu',
      children: children,
      minimum-items: 2
    %}
  </nav>
</header-menu>

Mobile Drawer

On mobile (below 750px), navigation switches to a drawer menu:
{% case variant %}
  {% when 'mobile' %}
    <div class="header__drawer" ref="headerDrawerContainer">
      {% render 'header-drawer',
        linklist: block_settings.menu,
        data_header_drawer_type: 'mobile-drawer'
      %}
    </div>
{% endcase %}
Optional horizontal scrolling navigation bar for mobile:
{% when 'navigation_bar' %}
  {% if block_settings.navigation_bar == true %}
    <div class="menu-list menu-list--mobile color-{{ block_settings.color_scheme_navigation_bar }}">
      <div class="menu-list__scroll-container">
        <ul class="menu-list__list">
          {% for link in block_settings.menu.links %}
            <li>
              <a href="{{ link.url }}" class="menu-list__item">
                {{ link.title }}
              </a>
            </li>
          {% endfor %}
        </ul>
      </div>
    </div>
  {% endif %}
{% endcase %}
Features:
  • Horizontal scroll on mobile
  • Gradient mask for scroll indication
  • Custom color scheme support

Mega Menu Features

The mega menu supports four content types:
Simple text-based dropdown menus.Setting: menu_style: 'text'
<a href="{{ link.url }}" class="mega-menu__link">
  {{ link.title }}
</a>

Grid System

Mega menus use a responsive grid:
<div class="mega-menu__grid" style="
  --menu-columns-tablet: {{ grid_columns_count_tablet }};
  --menu-columns-desktop: {{ grid_columns_count }};
  --menu-horizontal-gap: var(--gap-xl);
  --menu-vertical-gap: var(--gap-xl);
">
  {% render 'mega-menu-list',
    parent_link: link,
    grid_columns_count: 6,
    grid_columns_count_tablet: 4
  %}
</div>
Column Spans:
.mega-menu__column { grid-column: span 1; }
.mega-menu__column--span-2 { grid-column: span 2; }
.mega-menu__column--span-3 { grid-column: span 3; }
.mega-menu__column--span-4 { grid-column: span 4; }
{% for link in block_settings.menu.links %}
  <li class="menu-list__list-item">
    <a href="{{ link.url }}" 
       class="menu-list__link"
       {% if link.links != blank %}
         aria-controls="submenu-{{ forloop.index }}"
         aria-haspopup="true"
         aria-expanded="false"
       {% endif %}>
      <span class="menu-list__link-title">{{ link.title }}</span>
    </a>
    
    {% if link.links != blank %}
      <div class="menu-list__submenu" ref="submenu[]">
        <div id="submenu-{{ forloop.index }}" class="menu-list__submenu-inner">
          <div class="mega-menu section section--full-width-margin">
            <div class="mega-menu__grid">
              {% render 'mega-menu-list', parent_link: link %}
            </div>
          </div>
        </div>
      </div>
    {% endif %}
  </li>
{% endfor %}

Typography Settings

type_font_primary_size:
  options: [10px, 12px, 14px, 16px, 18px]
  default: 16px

type_font_primary_link:
  options: [body, subheading, heading, accent]
  default: heading

type_case_primary_link:
  options: [none, uppercase]
  default: none
CSS Variables:
.menu-list__link {
  font-family: var(--menu-top-level-font-family);
  font-size: var(--menu-top-level-font-size);
  font-weight: var(--menu-top-level-font-weight);
  text-transform: var(--menu-top-level-font-case);
}
menu_font_style:
  options:
    - regular (Small)
    - inverse (Medium)
    - inverse_large (Large)
  default: inverse
Snippet Usage:
<div style="{% render 'submenu-font-styles', settings: block_settings %}">
  <!-- Submenu content -->
</div>

Overflow Menu

When menu items don’t fit, they move to an overflow menu:
<li class="menu-list__list-item" slot="more">
  <button class="menu-list__link button-unstyled">
    <span class="menu-list__link-title">{{ 'actions.more' | t }}</span>
  </button>
</li>
Grid Layout for Overflow:
.overflow-menu::part(overflow-list) {
  display: grid;
  grid-template-columns: minmax(auto, 200px) 1fr;
  grid-template-areas: 'left right';
}

.menu-list__list-item[slot='overflow'] {
  display: contents;
  
  .menu-list__link {
    grid-area: left;
  }
  
  .menu-list__submenu {
    grid-area: right;
  }
}

Mobile Drawer Settings

Accordion Mode

drawer_accordion:
  label: Accordion
  default: false

drawer_accordion_expand_first:
  label: Expand first group
  default: false
  visible_if: drawer_accordion == true

Visual Options

drawer_dividers:
  label: Show dividers between items
  default: false

Active States

Current Page Indication

<a href="{{ link.url }}" 
   class="menu-list__link{% if link.active %} menu-list__link--active{% endif %}"
   {% if link.current %}
     aria-current="page"
   {% endif %}>
  {{ link.title }}
</a>

Hover Effects

/* Subdue non-hovered links */
.menu-list:has(.menu-list__list-item:hover) .menu-list__link {
  color: rgb(var(--menu-top-level-font-color-rgb) / var(--opacity-subdued-text));
}

/* Highlight hovered link */
.menu-list .menu-list__list-item:hover .menu-list__link {
  color: var(--menu-top-level-font-color);
}

Animation and Transitions

.menu-list__submenu {
  --submenu-content-opacity: 0;
  --submenu-content-animation: opacity calc(var(--submenu-animation-speed) * 0.75);
  
  visibility: hidden;
  position: absolute;
  transition: clip-path var(--submenu-animation-speed) var(--ease-out-cubic);
}

.menu-list__list-item:has([aria-expanded='true']) > .menu-list__submenu {
  --submenu-content-opacity: 1;
  visibility: visible;
}

Height Calculation

// Dynamically set submenu height for smooth animations
#header-component {
  --submenu-height: 0px;
  --full-open-header-height: 0px;
}

Performance Optimizations

Content Visibility

.header-menu .menu-list__submenu {
  content-visibility: auto;
  contain-intrinsic-size: 0px 500px;
}

/* Force visibility when open */
.header-menu details[open] .menu-list__submenu,
.header-menu .menu-list__submenu[data-active] {
  content-visibility: visible;
}

Scrollbar Styling

.menu-list__submenu-inner {
  max-height: calc(80vh - var(--header-height));
  overflow-y: auto;
  scrollbar-width: thin;
  scrollbar-color: rgb(var(--color-foreground-rgb) / var(--opacity-40)) transparent;
}

Accessibility Features

<nav aria-label="{{ 'accessibility.header_navigation_label' | t }}">
  <a aria-haspopup="true" aria-expanded="false" aria-controls="submenu-1">
    Menu Item
  </a>
</nav>
  • Tab through menu items
  • Enter/Space to expand submenus
  • Escape to close submenus
  • Arrow keys for navigation
{% if link.current %}
  aria-current="page"
{% endif %}

Schema Settings

{
  "name": "Menu",
  "settings": [
    {
      "type": "link_list",
      "id": "menu",
      "label": "Menu",
      "default": "main-menu"
    },
    {
      "type": "color_scheme",
      "id": "color_scheme",
      "default": "primary"
    },
    {
      "type": "select",
      "id": "menu_style",
      "options": [
        { "value": "text", "label": "None" },
        { "value": "collection_images", "label": "Collection Images" },
        { "value": "featured_products", "label": "Featured Products" },
        { "value": "featured_collections", "label": "Featured Collections" }
      ],
      "default": "collection_images"
    },
    {
      "type": "checkbox",
      "id": "navigation_bar",
      "label": "Show mobile navigation bar"
    },
    {
      "type": "checkbox",
      "id": "drawer_accordion",
      "label": "Use accordion for mobile drawer",
      "default": false
    }
  ]
}

JavaScript Module

The menu is powered by header-menu.js:
<script src="{{ 'header-menu.js' | asset_url }}" type="module" fetchpriority="low"></script>
Handles:
  • Menu open/close states
  • Overflow menu calculations
  • Touch and hover interactions
  • Submenu positioning
  • Mobile drawer functionality

Build docs developers (and LLMs) love