AMP

amp-mega-menu

Experimental

Description

Displays top-level navigational content inside expandable containers.

 

Required Scripts

<script async custom-element="amp-mega-menu" src="https://cdn.ampproject.org/v0/amp-mega-menu-0.1.js"></script>

Supported Layouts

Usage

Displays a horizontal navigation bar with menu items that open/close content containers on click.

<amp-mega-menu> provides a way to organize and display large collections of navigational content at the top of an AMP page. The component is intended primarily for desktop and tablet use cases, and it can be used jointly with <amp-sidebar> to create a responsive menu.

The <amp-mega-menu> component includes a single <nav> element containing either a <ul> or <ol>, where each <li> element is a menu item.

The <nav> element must be parented by either the <amp-mega-menu> component or a <template>, and it must have <ul> or <ol> as its only child.

Each menu item can contain any of the following tags as direct children:

  • <h1>, <h2>, <h3>, <h4>, <h5>, <h6>
  • <a>
  • <button>
  • <span>
  • <div>

Toggleable dropdowns

A menu item should have either one child (e.g. an anchor link or element with tap action), or two if the item expands into a dropdown container. In the latter case, the two children must conform to the following specs:

  1. A <button> or element with role=button: this element is used to toggle the dropdown container (but only if the former has no registered tap action) and receives focus when navigating between items.
  2. A <div> with role=dialog: this element will be rendered as a container that holds additional content under an item, and it is initially hidden.

A mask will cover the rest of the page when a dropdown is open. Content, such as a title banner, can appear above the mask. Apply a background color on the content and place it, alongside the <amp-mega-menu>, inside a <header> element.

Each dropdown may contain any of the following AMP elements:

  • <amp-ad>
  • <amp-carousel>
  • <amp-form>
  • <amp-img>
  • <amp-lightbox>
  • <amp-list>
  • <amp-video>

The example below demonstrates an <amp-mega-menu> with three menu items. The first two are toggleable and the third is an external link.

<amp-mega-menu height="30" layout="fixed-height">
  <nav>
    <ul>
      <li>
        <span role="button">Image</span>
        <div role="dialog">
          <amp-img
            src="/static/inline-examples/images/image1.jpg"
            width="300"
            height="200"
          ></amp-img>
        </div>
      </li>
      <li>
        <span role="button">List</span>
        <div role="dialog">
          <ol>
            <li>item 1</li>
            <li>item 2</li>
            <li>item 3</li>
          </ol>
        </div>
      </li>
      <li>
        <a href="https://amp.dev/">Link</a>
      </li>
    </ul>
  </nav>
</amp-mega-menu>
Open this snippet in playground

Dynamic content rendering

Fetch content of <amp-mega-menu> dynamically from a JSON endpoint using <amp-list> and <amp-mustache> template.

The example below demonstrates this ability by nesting <amp-list> inside <amp-mega-menu>.

<amp-mega-menu height="60" layout="fixed-height">
  <amp-list
    height="350"
    layout="fixed-height"
    src="/static/samples/json/product-single-item.json"
    single-item
  >
    <template type="amp-mustache">
      <nav>
        <ul>
{{#values}}          <li>
            <h4 role="button">{{name}}</h4>
            <div role="dialog">
              <amp-img
                src="{{img}}"
                width="320"
                height="213"
              ></amp-img>
              <p>Price: $<b>{{price}}</b></p>
            </div>
          </li>
{{/values}}        </ul>
      </nav>
    </template>
  </amp-list>
</amp-mega-menu>
Open this snippet in playground

Here is the JSON file used:

{
  "items": [
    {
      "values": [
        {
          "id": 1,
          "img": "/static/samples/img/product1_640x426.jpg",
          "name": "Apple",
          "price": "1.99"
        },
        {
          "id": 2,
          "img": "/static/samples/img/product2_640x426.jpg",
          "name": "Orange",
          "price": "0.99"
        },
        {
          "id": 3,
          "img": "/static/samples/img/product3_640x426.jpg",
          "name": "Pear",
          "price": "1.50"
        }
      ]
    }
  ]
}

Responsive design with <amp-sidebar>

Some viewports may be too narrow to display the content of <amp-mega-menu> in a single row. For these use cases, use media queries to switch between <amp-mega-menu> and <amp-sidebar>.

The example below hides <amp-mega-menu> when the viewport width is less than 500px. It replaces <amp-mega-menu> with a button that opens <amp-sidebar>.

<head