Products by Example

Fruit

Vegetable

More

View Demo View Source

Product Listing

Introduction

This sample showcases how to build a product listing page in AMP HTML.

Show Hidden Code Hide Code
<!doctype html>
<html ⚡>
<head>
  <meta charset="utf-8">
  <script async src="https://cdn.ampproject.org/v0.js"></script>

Additionally used AMP components must be imported in the header.

  <script async custom-element="amp-carousel" src="https://cdn.ampproject.org/v0/amp-carousel-0.1.js"></script>
Show Hidden Code Hide Code
  <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-form" src="https://cdn.ampproject.org/v0/amp-form-0.1.js"></script>
  <script async custom-element="amp-analytics" src="https://cdn.ampproject.org/v0/amp-analytics-0.1.js"></script>
  <script async custom-element="amp-sidebar" src="https://cdn.ampproject.org/v0/amp-sidebar-0.1.js"></script>

  <link rel="canonical" href="https://ampbyexample.com/samples_templates/product_listing/">
  <meta name="viewport" content="width=device-width,minimum-scale=1,initial-scale=1">
  <style amp-custom>
    article#preview {
      background: #ECEFF1;
    }
    /* general styling */
    article#preview {
      background-color: #f5f5f5;
    }
    amp-carousel {
      margin: 0;
    }
    /* header with logo and carousel */
    .header {
      position: relative;
      box-shadow: 0 2px 2px 0 rgba(0,0,0,.14),0 3px 1px -2px rgba(0,0,0,.2),0 1px 5px 0 rgba(0,0,0,.12);
      padding-top: 52px;
    }
    .header {
      background-color: #607D8B;
    }
    .header #hamburger {
      position:absolute;
      top:0;
      left: 0;
      font-size: 18px;
      font-weight: 500;
      color: white;
      text-transform: uppercase;
      padding: 13px;
    }
    .header #logo {
      position:absolute;
      top:0;
      left:36px;
      font-size: 18px;
      font-weight: 400;
      color: white;
      text-transform: uppercase;
      margin: 16px;
      height: 32px;
    }
    /* search form */
    .header form {
      padding: 0;
    }
    .header input::-webkit-search-decoration,
    .header input::-webkit-search-cancel-button {
      display: none;
    }
    .header input[type=submit] {
      position:absolute;
      top:10px; right:8px;
      background-color: #eb407a;
      background-position: center;
      background-repeat: no-repeat;
      background-image: -webkit-image-set(
        url('/img/ic_search_white_1x_web_24dp.png') 1x,
        url('/img/ic_search_white_2x_web_24dp.png') 2x
      );
      border: 0 none;
      height: 32px;
      width: 36px;
      -webkit-appearance: none;
      border-radius: 0;
      -moz-border-top-right-radius: 4px;
      -moz-border-bottom-right-radius: 4px;
      -webkit-border-top-right-radius: 4px;
      -webkit-border-bottom-right-radius: 4px;
      border-top-right-radius: 4px;
      border-bottom-right-radius: 4px;
    }
    .header input[type=search] {
      position: absolute;
      top: 10px; 
      right: 24px;
      background: #ededed ;
      padding: 0 8px;
      width: 20vw;
      height: 32px;
      font-family: inherit;
      font-size: 100%;
      -moz-box-sizing: border-box;
      -webkit-box-sizing: border-box;
      box-sizing: border-box;
      -webkit-appearance: none;
      border: solid 0px #ccc;
      border-radius: 0;
      -moz-border-top-left-radius: 4px;
      -moz-border-bottom-left-radius: 4px;
      -webkit-border-top-left-radius: 4px;
      -webkit-border-bottom-left-radius: 4px;
      border-top-left-radius: 4px;
      border-bottom-left-radius: 4px;
      -webkit-transition: all .9s;
      -moz-transition: all .9s;
      transition: all .9s ease;
    }
    .header input[type=search]:focus {
      box-sizing: border-box;
      width: 80vw;
      max-width: 700px;
      height: 32px;
      background-color: #fff;
      border-color: #eb407a;
      -webkit-box-shadow: 0 0 5px rgba(109,207,246,.5);
      -moz-box-shadow: 0 0 5px rgba(109,207,246,.5);
      box-shadow: 0 0 5px rgba(109,207,246,.5);
      outline:none;
    }
    .header input:-moz-placeholder,
    .header input::-webkit-input-placeholder {
      color: #999;
    }
    .header input:focus + #logo {
      visibility: hidden;
      opacity: 0;
      transition: visibility 0s 0.7s, opacity 0.7s ease;
    }
    .header input + #logo {
      visibility: visible;
      opacity: 1;
      transition: opacity 1.5s ease;
    }
    @media (min-width: 600px) {
      .header input[type=search] {
        width: 100px;
      }
      .header input[type=search]:focus {
        width: 600px;
      }
    }
    /* items */
    .items,
    amp-list.items > div {
      display: flex;
      justify-content:space-around;
      flex-wrap: wrap;
    }
    .item {
      flex-grow: 1;
      flex-shrink: 1;
    }
    /* tiles */
    .tile {
      background-color: white;
      width: 120px;
      height: 200px;
      display: block;
      margin: 8px;
      -webkit-tap-highlight-color: #eee;
      max-width: 200px;
    }
    @media (max-width: 500px) {
      .items .tile {
        width: 150px;
        height: 200px;
      }
    }
    .tile:active {
      background-color: #eee;
    }
    .tile p {
      margin: 0;
      padding: 0 8px;
      font-size: 14px;
      line-height:20px;
    }
    .tile .name {
      margin-top: 8px;
    }
    .tile .price {
      margin-bottom: 8px;
    }
    .tile .price,
    .tile .star {
      color: black;
    }
    .product-carousel {
      margin: 16px;
    }
    .product-carousel .tile {
      margin: 8px 0;
    }
    #hero-images {
        object-fit: contain;
    }
    #hero-images .caption {
      text-align: center;
      position: absolute;
      bottom: 0;
      left: 0;
      right: 0;
      padding: 24px;
      background: rgba(200, 200, 200, 0.8);
      color: #333;
      font-size: 36px;
      max-height: 30%;
      font-weight: 300;
    }
  </style>

  <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>
</head>
<body>

Use the amp-sidebar component to give customers the chance to quickly jump to any of your product categories.

  <amp-sidebar id="drawermenu"
      layout="nodisplay">
    <div class="topheader">
      <a href="/"
          class="home">Products by Example</a>
    </div>
    <hr/>
    <h4 class="category expanded">
      <a href="/samples_templates/product_listing/preview/">Fruit</a>
    </h4>
    <h4 class="category">
      <a href="/samples_templates/product_listing/preview/">Vegetable</a>
    </h4>
    <h4 class="category">
      <a href="/samples_templates/product_listing/preview/">More</a>
    </h4>
  </amp-sidebar>

AMP supports forms, which means you can directly integrate a product search into your AMPs. Try searching for "Apple".

AMP doesn't support custom Javascript, but you can use CSS3 animations to enrich your page. The expanding text field when the search box is focused is implemented with CSS only.

  <div class="header">
    <a id="hamburger"
        on="tap:drawermenu.toggle">
      <amp-img srcset="/img/ic_menu_white_1x_web_24dp.png 1x, /img/ic_menu_white_2x_web_24dp.png 2x"
          width="24"
          height="24"
          alt="navigation"></amp-img>
    </a>
    <form method="GET"
        action="https://ampbyexample.com/samples_templates/product_listing/search"
        target="_top">
      <input name="search"
          type="search"
          placeholder="Search">
      <a id="logo"
          href="/">Products by Example</a>
      <input type="submit"
          value="">
    </form>
  </div>

A Hero Slider

The amp-carousel component can be used to quickly create full-bleed, auto-advancing slideshows showcasing your latest promotions.

  <amp-carousel id="hero-images"
      width="1024"
      height="480"
      layout="responsive"
      type="slides"
      autoplay>
    <a href="#">
      <amp-img src="/img/product_hero1_1024x683.jpg"
          layout="fill"
          alt="product hero 1"
          attribution="visualhunt"></amp-img>
      <div class="caption">The 10 best Apples</div>
    </a>
    <a href="#">
      <amp-img src="/img/product_hero2_1024x683.jpg"
          layout="fill"
          alt="product hero 2"
          attribution="visualhunt"></amp-img>
      <div class="caption">So much orange!</div>
    </a>
    <a href="#">
      <amp-img src="/img/product_hero3_1024x683.jpg"
          layout="fill"
          alt="product hero 3"
          attribution="visualhunt"></amp-img>
      <div class="caption">So healthy.</div>
    </a>
  </amp-carousel>
Show Hidden Code Hide Code

  <h5>Fruits</h5>

  <div class="items">
    
    <a class="tile item"
        href="/samples_templates/product/">
      <amp-img width="640"
          height="426"
          layout="responsive"
          alt="Apple"
          src="/img/product1_640x426.jpg"></amp-img>
      <p class="name">Apple</p>
      <p class="star">★★★★★</p>
      <p class="price">$1.99</p>
    </a>
    
    <a class="tile item"
        href="/samples_templates/product/">
      <amp-img width="640"
          height="426"
          layout="responsive"
          alt="Orange"
          src="/img/product2_640x426.jpg"></amp-img>
      <p class="name">Orange</p>
      <p class="star">★★★★☆</p>
      <p class="price">$0.99</p>
    </a>
    
    <a class="tile item"
        href="/samples_templates/product/">
      <amp-img width="640"
          height="426"
          layout="responsive"
          alt="Pear"
          src="/img/product3_640x426.jpg"></amp-img>
      <p class="name">Pear</p>
      <p class="star">★★★☆☆</p>
      <p class="price">$1.50</p>
    </a>
    
    <a class="tile item"
        href="/samples_templates/product/">
      <amp-img width="640"
          height="426"
          layout="responsive"
          alt="Banana"
          src="/img/product4_640x426.jpg"></amp-img>
      <p class="name">Banana</p>
      <p class="star">★★★★★</p>
      <p class="price">$1.50</p>
    </a>
    
  </div>

Offers & Highlights

  <h5 class="deals">Recommendations</h5>
Recommendations

The amp-carousel supports also a more traditional carousel mode.

  <amp-carousel class="product-carousel"
      width="auto"
      height="160"
      layout="fixed-height"
      type="carousel"
      autoplay>
    <a class="tile"
        href="#"
        role="listitem">
      <amp-img width="640"
          height="426"
          layout="responsive"
          alt="Apple"
          src="/img/product1_640x426.jpg"></amp-img>
      <p class="name">Apple</p>
      <p class="star">★★★★★</p>
      <p class="price">$1.99</p>
    </a>
    <a class="tile"
        href="#"
        role="listitem">
      <amp-img width="640"
          height="426"
          layout="responsive"
          alt="Orange"
          src="/img/product2_640x426.jpg"></amp-img>
      <p class="name">Orange</p>
      <p class="star">★★★★☆</p>
      <p class="price">$0.99</p>
    </a>
    <a class="tile"
        href="#"
        role="listitem">
      <amp-img width="640"
          height="426"
          layout="responsive"
          alt="Pear"
          src="/img/product3_640x426.jpg"></amp-img>
      <p class="name">Pear</p>
      <p class="star">★★★☆☆</p>
      <p class="price">$1.50</p>
    </a>
    <a class="tile"
        href="#"
        role="listitem">
      <amp-img width="640"
          height="426"
          layout="responsive"
          alt="Banana"
          src="/img/product4_640x426.jpg"></amp-img>
      <p class="name">Banana</p>
      <p class="star">★★★★★</p>
      <p class="price">$1.50</p>
    </a>
    <a class="tile"
        href="#"
        role="listitem">
      <amp-img width="640"
          height="426"
          layout="responsive"
          alt="Apple"
          src="/img/product1_640x426.jpg"></amp-img>
      <p class="name">Apple 2</p>
      <p class="star">★★★★★</p>
      <p class="price">$1.99</p>
    </a>
    <a class="tile"
        href="#"
        role="listitem">
      <amp-img width="640"
          height="426"
          layout="responsive"
          alt="Orange"
          src="/img/product2_640x426.jpg"></amp-img>
      <p class="name">Orange 2</p>
      <p class="star">★★★★☆</p>
      <p class="price">$0.99</p>
    </a>
    <a class="tile"
        href="#"
        role="listitem">
      <amp-img width="640"
          height="426"
          layout="responsive"
          alt="Pear"
          src="/img/product3_640x426.jpg"></amp-img>
      <p class="name">Pear 2</p>
      <p class="star">★★★☆☆</p>
      <p class="price">$1.50</p>
    </a>
    <a class="tile"
        href="#"
        role="listitem">
      <amp-img width="640"
          height="426"
          layout="responsive"
          alt="Banana"
          src="/img/product4_640x426.jpg"></amp-img>
      <p class="name">Banana 2</p>
      <p class="star">★★★★★</p>
      <p class="price">$1.50</p>
    </a>
  </amp-carousel>
  <h5 class="deals">Bestsellers</h5>
Bestsellers

With AMP, you can easily pull in different latest offers or highlights without changing the page. To do so, just use amp-list to fire a CORS request to a JSON endpoint which supplies the list of related products. These are populated into an amp-mustache template on the client. Learn more about amp-list here

  <amp-list class="items"
      width=200
      height=100
      layout=responsive
      src="/json/related_products.json">
    <template type="amp-mustache">
      <a class="tile item"
          href="/samples_templates/product/preview/">
        <amp-img width="640"
            height="426"
            layout="responsive"
            alt="{{name}}"
            src="{{img}}"></amp-img>
        <p class="name">{{name}}</p>
        <p class="star">{{{stars}}}</p>
        <p class="price">${{price}}</p>
      </a>
    </template>
  </amp-list>

Analytics

Analytics must be configured in the body. Here we use Google Analytics to track pageviews.

  <amp-analytics type="googleanalytics">
    <script type="application/json">
      {
        "vars": {
          "account": "UA-80609902-1"
        },
        "triggers": {
          "default pageview": {
            "on": "visible",
            "request": "pageview",
            "vars": {
              "title": "{{title}}"
            }
          }
        }
      }
    </script>
  </amp-analytics>

Next up:

</body>
</html>