component-nav-megamenu Snippet
snippets/component-nav-megamenu.liquid renders a full-width megamenu navigation layout for desktop headers. When a menu item with children is clicked, it expands a wide dropdown panel below the header using a 6-column grid layout. The megamenu supports 3 levels of navigation (parent → child → grandchild) and uses Alpine.js for toggle behavior and smooth transitions.
What It Does
- Renders a full-width megamenu that expands below the header.
- Uses a 6-column grid layout to display child links in organized columns.
- Supports 3 levels of navigation hierarchy (parent → child → grandchild).
- Provides toggleable megamenu panels using Alpine.js state management.
- Uses smooth transitions for megamenu show/hide animations.
- Marks current page links with
aria-current="page". - Handles click-outside detection to close open megamenus.
Parameters
| Parameter | Type | Default | Description |
|---|---|---|---|
menu | linklist | required | Menu object (linklist) to render. |
menu_color_scheme | string | optional | Color scheme handle for megamenu background styling. |
Dependencies & Assets
| Type | Files / Components |
|---|---|
| CSS | Inline {% stylesheet %} block with comprehensive megamenu styling |
| JavaScript | Alpine.js (required for megamenu state management) |
| Icons | icon-caret.svg (inline via inline_asset_content) |
| Data | Requires menu linklist object with links array |
- Alpine.js powers megamenu state (
x-data,x-show,@click.outside). - Inline styles provide all megamenu-specific CSS (no external CSS file required).
- Grid layout uses CSS Grid with 6 columns for organized child link display.
Dynamic Styles
The snippet includes inline styles for megamenu positioning, grid layout, and typography:
{% stylesheet %}
#main-header .nav-megamenu {
position: absolute;
left: 0;
top: 100%;
width: 100%;
margin-top: 1px;
}
#main-header .nav-megamenu .page-width {
display: grid;
grid-template-columns: repeat(6, minmax(0, 1fr));
margin-inline: auto;
align-items: flex-start;
padding: 30px 20px;
}
/* ... additional styling ... */
{% endstylesheet %}- Full-width positioning: Megamenu spans entire header width with
width: 100%andleft: 0. - Grid layout: Uses 6-column grid (
grid-template-columns: repeat(6, minmax(0, 1fr))) for organized child links. - Absolute positioning: Positioned absolutely below header with
top: 100%. - Page width container: Inner content uses
.page-widthclass for centered, constrained width.
Markup Structure
<ul>
{% for link in menu.links %}
<li x-data="{ menuOpen: false }" @click.outside="menuOpen = false">
{% if link.links != blank %}
<!-- Parent link with megamenu -->
{% else %}
<!-- Simple link without megamenu -->
{% endif %}
</li>
{% endfor %}
</ul>- Alpine.js state: Each top-level menu item has independent state for megamenu visibility.
- Click outside: Closes megamenu when clicking outside via
@click.outside.
Parent Link with Megamenu
{% if link.links != blank %}
<button
@click="menuOpen = !menuOpen"
:class="{ 'menu-open': menuOpen }"
class="menu-toggle"
>
{{- link.title | escape -}}
{{- 'icon-caret.svg' | inline_asset_content -}}
</button>
<div
x-show="menuOpen"
x-transition
x-cloak
class="nav-megamenu color-{{ menu_color_scheme }} gradient"
>
<!-- Grid layout with child links -->
</div>
{% endif %}- Toggle behavior: Clicking button toggles megamenu visibility.
- Caret icon: Shows caret icon to indicate expandable menu.
- Alpine.js directives:
@click="menuOpen = !menuOpen": Toggles megamenu:class="{ 'menu-open': menuOpen }": Adds class when openx-show="menuOpen": Shows/hides megamenux-transition: Smooth show/hide animationx-cloak: Prevents flash of unstyled content
Megamenu Grid Layout
<div class="nav-megamenu color-{{ menu_color_scheme }} gradient">
<ul class="page-width" role="list">
{%- for childlink in link.links -%}
<li>
<a href="{{ childlink.url }}" class="nav-megamenu_heading" {% if childlink.current %}aria-current="page"{% endif %}>
{{ childlink.title | escape }}
</a>
{%- if childlink.links != blank -%}
<ul class="nav-megamenu_child" role="list">
{%- for grandchildlink in childlink.links -%}
<li>
<a href="{{ grandchildlink.url }}" {% if grandchildlink.current %}aria-current="page"{% endif %}>
{{ grandchildlink.title | escape }}
</a>
</li>
{%- endfor -%}
</ul>
{%- endif -%}
</li>
{%- endfor -%}
</ul>
</div>- 6-column grid: Child links displayed in 6-column grid layout.
- Child headings: Child links styled as headings (
nav-megamenu_heading) with bold font weight. - Grandchild links: Nested grandchild links displayed below child headings.
- Current page indication: Links to current page marked with
aria-current="page".
Simple Link (No Megamenu)
{% else %}
<a
href="{{ link.url }}"
{% if link.current %}
aria-current="page"
{% endif %}
>
{{- link.title | escape -}}
</a>
{% endif %}- Direct link: Simple link without megamenu when parent has no children.
Behavior
- Megamenu toggle: Clicking parent link with children opens/closes its megamenu.
- Click outside: Clicking outside closes open megamenu.
- Smooth transitions: Alpine.js
x-transitionprovides smooth show/hide animations. - Current page indication: Links to current page marked with
aria-current="page". - Full-width display: Megamenu spans entire header width for maximum content space.
- Grid organization: Child links organized in 6-column grid for easy scanning.
Usage Example
{% render 'component-nav-megamenu',
menu: section.settings.menu,
menu_color_scheme: section.settings.menu_color_scheme
%}Typically used in:
- Header (
sections/header.liquid) whenmenu_type_desktop == 'mega'or not 'dropdown'/'drawer' - Desktop navigation (not used on mobile - mobile uses drawer)
Implementation Notes
Alpine.js requirement: Snippet requires Alpine.js to be loaded in the theme for megamenu state management.
Full-width layout: Megamenu spans entire header width (
width: 100%,left: 0) for maximum content space.Grid layout: Uses CSS Grid with 6 columns (
grid-template-columns: repeat(6, minmax(0, 1fr))) to organize child links.State management: Each top-level menu item has independent Alpine.js state:
menuOpen: Controls megamenu visibility
Click outside handling: Uses
@click.outsidedirective to close megamenu when clicking outside.Icon dependency: Requires
icon-caret.svgin theassets/folder for expandable menu indicators.CSS class dependencies: Snippet relies on CSS classes:
.nav-megamenu.menu-toggle.menu-open.nav-megamenu_heading.nav-megamenu_child.page-width.color-\{\{ menu_color_scheme \}\}.gradient
Alpine.js directives:
x-data="{ menuOpen: false }": Initializes state per menu item@click="menuOpen = !menuOpen": Toggles megamenu:class="{ 'menu-open': menuOpen }": Adds class when megamenu openx-show="menuOpen": Shows/hides megamenux-transition: Provides smooth show/hide animationsx-cloak: Prevents flash of unstyled content@click.outside="menuOpen = false": Closes megamenu on outside click
Title escaping: All link titles are escaped using
escapefilter for security.Current page detection: Uses
link.current,childlink.current, andgrandchildlink.currentto detect current page.Accessibility features:
aria-current="page"for current page linksrole="list"for semantic structure- Proper link semantics
- Keyboard navigation support via Alpine.js
Color scheme integration: Megamenu uses theme color scheme via
color-\{\{ menu_color_scheme \}\}class.Gradient class: Megamenu includes
gradientclass for additional styling options.Page width container: Inner content uses
.page-widthclass for centered, constrained width matching theme page width.Grid column distribution: Child links distributed evenly across 6 columns using
minmax(0, 1fr)for flexible sizing.Child link styling: Child links styled as headings with
font-weight: 600for visual hierarchy.Grandchild link styling: Grandchild links have reduced padding (
padding: 6px 0) and standard font size.Megamenu padding: Grid container has
padding: 30px 20pxfor comfortable spacing.Grid alignment: Grid items aligned to top with
align-items: flex-startfor consistent layout.Nested submenu positioning: Grandchild links use
position: staticto appear inline below child headings.Transition animations: Megamenu show/hide uses Alpine.js
x-transitionfor smooth animations.Multiple megamenus: Only one megamenu can be open at a time (controlled by independent
menuOpenstate per menu item).No translation keys: Menu labels come directly from Shopify menu object, not translation files.
Menu link structure: Relies on Shopify's menu structure:
menu.links: Top-level linkslink.links: Child linkschildlink.links: Grandchild links
Empty link check: Uses
link.links != blankto determine if link has children.Caret icon display: Caret icon shown for all links with children to indicate expandable menu.
Link URL handling: All links use
link.url,childlink.url,grandchildlink.urlfrom Shopify menu object.Security: All user-generated content (link titles) is escaped using
escapefilter.Responsive behavior: Megamenu designed for desktop - mobile typically uses drawer navigation instead.
Z-index management: Megamenu should have appropriate z-index to appear above other content (handled by CSS).
Header context: Megamenu styles scoped to
#main-headerto avoid conflicts with other navigation.Grid responsiveness: 6-column grid may need media query adjustments for smaller screens (handled by theme CSS).
Button semantics: Uses
<button>element for toggle, which is semantically correct for interactive elements.No JavaScript file: Snippet doesn't require a separate JavaScript file - all behavior handled by Alpine.js.
Performance: Inline styles prevent additional HTTP request but increase HTML size.
Accessibility improvements needed: Consider adding:
aria-expandedattributes for megamenu togglesaria-haspopupattributes- Keyboard navigation enhancements
- Focus management when megamenu opens/closes
Grid column count: Fixed 6-column grid may not be optimal for all menu structures. Consider making it configurable or responsive.
Child link distribution: Child links distributed evenly across columns - if there are fewer than 6 child links, some columns will be empty.
Grandchild link display: Grandchild links displayed as simple vertical list below child headings.
Margin and spacing: Megamenu has
margin-top: 1pxto create slight gap from header, and grid container has internal padding.Centered content: Grid container uses
margin-inline: autofor horizontal centering within full-width megamenu.Heading font weight: Child links use
font-weight: 600to distinguish them from grandchild links.Link hierarchy: Visual hierarchy created through:
- Child links: Bold headings
- Grandchild links: Regular text with reduced padding
Menu depth limit: Supports exactly 3 levels of nesting (parent, child, grandchild). Deeper nesting not supported.
Desktop-only: Megamenu designed for desktop navigation - mobile navigation typically uses drawer component.
Full-width advantage: Full-width layout allows for rich content display, ideal for large navigation structures.
Grid flexibility: Grid uses
minmax(0, 1fr)to allow columns to shrink below content size if needed.Page width constraint: Inner content constrained by
.page-widthclass to match theme's page width setting.Color scheme scoping: All styles scoped to
#main-headerto ensure they only apply in header context.Transition timing: Alpine.js
x-transitionprovides default transition timing - can be customized via CSS.