AMP Tabbed Menu Demo Source Code

A Tabbed Menu Implemented in AMP Bind and AMP List code example

An AMP Tech Guide

 
This page shows crucial snippets of the code used on AMP page that uses AMP List and AMP Bind to implement a tabbed menu.
Required tags in the document head:

<!-- Required tags: Charset,  canonical link, and viewport -->
<meta charset="utf-8">
<link rel="canonical" href="https://www.stonetemple.com/amp/examples/amp-tabbed-menu-demo-code.html">
<meta name="viewport" content="width=device-width,minimum-scale=1,initial-scale=1">
<!-- Required: The AMP project default CSS and noscript -->
<style amp-boilerplate>body{-webkit-animation:-amp-start 8s steps(1,end) 0s 1 normal both;-moz-animation:-amp-start 8s steps(1,end) 0s 1 normal both;-ms-animation:-amp-start 8s steps(1,end) 0s 1 normal both;animation:-amp-start 8s steps(1,end) 0s 1 normal both}@-webkit-keyframes -amp-start{from{visibility:hidden}to{visibility:visible}}@-moz-keyframes -amp-start{from{visibility:hidden}to{visibility:visible}}@-ms-keyframes -amp-start{from{visibility:hidden}to{visibility:visible}}@-o-keyframes -amp-start{from{visibility:hidden}to{visibility:visible}}@keyframes -amp-start{from{visibility:hidden}to{visibility:visible}}</style><noscript><style amp-boilerplate>body{-webkit-animation:none;-moz-animation:none;-ms-animation:none;animation:none}</style></noscript>
<!-- Required: The AMP Project JS -->
<script async src="https://cdn.ampproject.org/v0.js"></script>

The custom CSS is put inside a style tag with the attribute name amp-custom.

<style amp-custom>
 body {
      font-family: "Helvetica", "Arial", sans-serif;
      padding-top: 60px;
      line-height: 1.6em;
      font-weight: normal;
      font-size: 16px;
      margin: 0;
    }
    p {
      margin: 0px 0px 18px;
    }
    a {
      color: #66ac2f;
      cursor: pointer;
    }
    a:hover {
      text-decoration: none;
    }
    .content {
      max-width: 700px;
      width: 100%;
      margin: 20px auto 50px;
    }
    .wrapper {
      padding: 0px 24px;
    }
  .header.fixed{left:0;position:fixed;top:0;transform:translateY(0%);transition:all .4s ease;width:100%;z-index:1000;
    height: 44px; background-color: #1f70a8;}
     .header.fixed a {text-decoration: none;color:#fff;}
      .header.fixed a:hover {text-decoration: underline;}
    h1 {
    text-align: center;
  font-size: 36px;
    line-height: 44px;
  font-family: tahoma, arial, sans-serif;
  color: #056772;
  margin: 0 auto;
  height: 150px;
      max-width: 400px;
  width: 100%;
  }
    .title p {
      color: #ffffff;
      padding: 10px 0px 0px;
      text-align: center;
      margin: 0px;
    }
     footer p {
      font-size: 14px;
    }
    footer {
      background-color: #808183;
      text-align: center;
      color: #ffffff;
      padding: 14px 0px 0px;
      overflow: hidden;
    }
  h1 span#bigh1 {
    font-size: 36px;
  line-height: 44px;
  padding-top: 0;
  margin-top: 0;
  }
 h2, h4 {
   text-align: center;
   margin: 10px 0px 16px;
 }
    h3 {
      margin: 20px 0px 10px;
      color:#1f70a8;
      padding-bottom: 6px;
      border-bottom: 1px dashed #1f70a8;
    }
  .contentbox {
    border: 1px solid #3197a3;
    padding: 24px;
  }
  #key {
    width: 100%;
padding-bottom: 20px;
  box-sizing: border-box;
  text-align: center;
  }
  #goTabs {
    width: 100%;
  height: 38px;
  box-sizing: border-box;
  font-size: 22px;
  line-height: 26px;
    margin-bottom:0px;
    color: #fff;
  }
  #goTabs button{
    border: 1px solid #;
  border-radius: 3px;
  border-bottom-left-radius: 0;
  border-bottom-right-radius: 0;
  padding: 5px 15px;
  border-bottom: 0;
  color:#fff;
  font-size: 18px;
  line-height: 26px;
    margin:0;
     cursor: pointer;
  }
  #goTabs button.active, #goTabs button:hover {
    border: 1px #3197a3 solid;
  background-color: #3197a3;
  }
  #goTabs button.inactive {
    background-color: #056772;
  border: 1px #056772 solid;
  }
  #menu{
    width:100%;
    height:auto;
    overflow:scroll;
  box-sizing:border-box;
  }
    #menu table {
      max-width: 400px;margin: 0 auto 30px;
    }
  #location {
    width: 100%;
    height: auto;
  box-sizing:border-box;
  }
    #location iframe {
      min-height: 470px;
      position: relative;
    }
  #hours {
    text-align: center;
    width: 100%;
    height: auto;
    box-sizing:border-box;
  }
  #hours p {
    font-size: 18px;
  line-height: 1.6em;
  }
  span#message {
  font-style:italic;
  }
  td.cellFill {
    width: 5px;
  height: 1px;
  }
  td.lilFill {
    width: 1px;
  height: 1px;
  }
  .show {
    display: block;
  }
  .hide {
    display: none;
  }
    .foot {
      text-align: center;
      margin: 30px auto 20px;
    }
@media screen and (max-width: 639px) {
    h1{
    height: 120px;
  }
}
@media screen and (min-width: 640px) {
   h1{
    height: 150px;
  }
}
</style>

AMP components used in this example:

<!-- These are AMP components that enable functionality used on this page (AMP-bind, AMP-list, AMP-iframe and AMP-mustache). Include components as needed -->
<script async custom-element="amp-bind" src="https://cdn.ampproject.org/v0/amp-bind-0.1.js"></script>
<script async custom-element="amp-list" src="https://cdn.ampproject.org/v0/amp-list-0.1.js"></script>
<script async custom-template="amp-mustache" src="https://cdn.ampproject.org/v0/amp-mustache-0.1.js"></script>
<script async custom-element="amp-iframe" src="https://cdn.ampproject.org/v0/amp-iframe-0.1.js"></script>

All of the preceding code blocks should be put in the document head. The following code blocks should reside in the document body.
Here’s the code used to call out if the restaurant is currently open. It uses AMP-list

<!-- this AMP-list makes an async call to find out if the restaurant is open right now. The AMP-mustache component is used to display the message -->
  <amp-list width="auto"
  height="25"
  layout="fixed-height"
  src="halloa-hours.php">
  <template type="amp-mustache">
   <span id="message">{{message}}</span>
  </template>
</amp-list>

Here’s the code used to alter the states of the tabbed content and tab menu

<!-- The following script is used to navigate the tabs Menu, Location and Hours. It sets the class names used for the tabs and the tabbed content.  -->
<amp-state id="theTabs">
  <script type="application/json">
    {
      "menu": {
        "menuTab": "active",
        "locationTab": "inactive",
    "hoursTab": "inactive",
    "menu": "contentbox show",
        "location": "contentbox hide",
    "hours": "contentbox hide"
      },
      "location": {
        "menuTab": "inactive",
        "locationTab": "active",
    "hoursTab": "inactive",
    "menu": "contentbox hide",
        "location": "contentbox show",
    "hours": "contentbox hide"
      },
    "hours": {
        "menuTab": "inactive",
        "locationTab": "inactive",
    "hoursTab": "active",
    "menu": "contentbox hide",
        "location": "contentbox hide",
    "hours": "contentbox show"
      }
    }
  </script>
</amp-state>

HTML code for the the tab menu

<!-- These are the tabs the user clicks to view content in the different tabs. This features uses AMP-bind -->
  <div id="goTabs">
    <button id="goMenu" on="tap:AMP.setState({ currentTab: 'menu' })" class="active" [class]="theTabs[currentTab].menuTab"> Menu </button>
    <button id="goLocation" on="tap:AMP.setState({ currentTab: 'location' })" class="inactive" [class]="theTabs[currentTab].locationTab"> Location </button>
    <button id="goHours" on="tap:AMP.setState({ currentTab: 'hours' })" class="inactive" [class]="theTabs[currentTab].hoursTab"> Hours </button>
  </div>

The following block contains the shell for the tabbed content as well as the iframe that contains the Google map

<!-- The tabbed content (fundamentally three DIV elements, each with a unique id (menu, location, hours)) starts here -->
  <div id="menu"  class="contentbox show" [class]="theTabs[currentTab].menu">
  <h2>Menu</h2>
  <!-- Menu HTML removed in this example to reduce size of code block -->
  </div>
  <div id="location" class="contentbox hide" [class]="theTabs[currentTab].location">
  <!-- The placeholder image is required in order to put the iframe this close to the top of the page -->
    <amp-iframe sandbox="allow-scripts allow-same-origin" layout="responsive" frameborder="0" src="https://www.google.com/maps/embed/v1/place?q=route%209%20southborough%20ma&key=AIzaSyAH3adapj2fjLF4zND2DB9mN5N7lgImWnY" width="496" height="500" frameborder="0"  allowfullscreen><amp-img layout="fill" src="https://www.stonetemple.com/amp/images/placeholder-new.png" placeholder></amp-img></amp-iframe>
  </div>
  <div id="hours" class="contentbox hide" [class]="theTabs[currentTab].hours">
    <p>
      Monday-Thursday 11am -10 pm<br>
      Friday 11am -11pm<br>
      Saturday 11am - 11pm<br>
      Sunday 11am - 9pm
    </p>
  </div>
</div>
<!-- this is the end of the tabbed content -->

 

Subscribe to the Weekly Blog Digest:

Sign Up