Description A rich, visual storytelling format.
Availability
Required Script <script async custom-element="amp-story" src="https://cdn.ampproject.org/v0/amp-story-0.1.js"></script>
Supported Layouts none
Examples

Overview

The amp-story extension provides a new format for displaying visual content that you can assemble into a story-telling experience. With an AMP Story, you can provide users with bite-sized, visually rich information and content.

AMP Story format

An AMP Story is a complete AMP HTML document that is comprised of pages, within the pages are layers, within the layers are AMP & HTML elements, like media, analytics, text, and so on.

Boilerplate

The following markup is a decent starting point or boilerplate. Copy this and save it to a file with a .html extension.

<!doctype html>
<html amp lang="en">
  <head>
    <meta charset="utf-8">
    <script async src="https://cdn.ampproject.org/v0.js"></script>
    <script async custom-element="amp-story"
        src="https://cdn.ampproject.org/v0/amp-story-0.1.js"></script>
    <title>Hello, amp-story</title>
    <link rel="canonical" href="http://example.ampproject.org/my-story.html" />
    <meta name="viewport"
        content="width=device-width,minimum-scale=1,initial-scale=1">
    <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>
    <amp-story standalone>
      <amp-story-page id="my-first-page">
        <amp-story-grid-layer template="fill">
          <amp-img src="https://example.ampproject.org/helloworld/bg1.jpg"
              width="900" height="1600">
          </amp-img>
        </amp-story-grid-layer>
        <amp-story-grid-layer template="vertical">
          <h1>Hello, amp-story!</h1>
        </amp-story-grid-layer>
      </amp-story-page>
      <amp-story-page id="my-second-page">
        <amp-story-grid-layer template="fill">
          <amp-img src="https://example.ampproject.org/helloworld/bg2.gif"
              width="900" height="1600">
          </amp-img>
        </amp-story-grid-layer>
        <amp-story-grid-layer template="vertical">
          <h1>The End</h1>
        </amp-story-grid-layer>
      </amp-story-page>
    </amp-story>
  </body>
</html>

The content in the body creates a story with two pages. Each page has a full bleed background image, with a simple string of text on top of it.

Required markup for amp-story

The AMP Story HTML format follows the same markup requirements as a valid AMP HTML document, along with the following additional requirements:

RULE DESCRIPTION
The <amp-story standalone> element is the only child element of <body>. Identifies that the document is an AMP Story.
Contain a <script async src="https://cdn.ampproject.org/v0/amp-story-0.1.js" custom-element="amp-story"></script> tag as the third child of their <head> tag. Includes and loads the amp-story JS library.

Story: amp-story

The amp-story component represents an entire story. The component itself implements the UI shell, including handling gestures and navigation, and inserting the application shell UI (controls, progress bar, etc).

Example

<amp-story standalone bookend-config-src="./related.json" background-audio="my.mp3">
  <amp-story-page>[...]</amp-story-page>
  <amp-story-page>[...]</amp-story-page>
  <amp-story-page>[...]</amp-story-page>
</amp-story>

Attributes

standalone [required]

Identifies that the AMP document is a story.

bookend-config-src [optional]

A URL endpoint that accepts GET requests and returns a JSON response with links to related and trending stories, to be shown on a screen at the end of the story. If omitted, the amp-story component renders a default UI for the end screen. See the bookend endpoint section below for the JSON response format.

background-audio [optional]

A URI to an audio file that plays throughout the story.

Children (of amp-story)

The <amp-story> component contains one or more <amp-story-page> components, containing each of the individual screens of the story. The first page specified in the document order is the first page shown in the story.

Bookend JSON endpoint

The bookend-config-src value is a URL endpoint that returns data for the end screen of the story, containing related links, etc. The system is responsible for fetching the data necessary to render related and trending articles. This can be served from a static JSON file, or dynamically-generated (e.g., to calculate what is currently trending).

The end screen displays related articles in sections. The heading for the section is obtained from the provided string key name (e.g., "More to Read"); the array of articles for that key are displayed for that section. The domain and favicon of each linked article are automatically parsed and fetched from the specified URL for each piece of content.

These are configured in the related-articles field of the response object.

Social sharing

The configuration for social sharing is defined in the share-providers field of the response object (optional).

This field should contain an object with key-value pairs. Each key represents a share provider's name (e.g. facebook). The value should be set to a non-empty configuration object for the provider or true (when no parameters are required).

The list of available providers is the same as in the amp-social-share component.

Each of these providers has a different set of available parameters (see data-param-*). The configuration object takes these parameters without the data-param- preffix (for example, the data-param-app_id would appear in the configuration object as app_id).

Example JSON response

{
  "share-providers": {
    "email": true,
    "twitter": true,
    "tumblr": true,
    "facebook": {
      // Facebook requires an `app_id` param
      "app_id": "MY_FACEBOOK_APP_ID"
    }
  },
  "related-articles": {
    "More to Read": [
      {
        "title": "My friends, this is India [...]",
        "url": "http://a-publisher.com/india",
        "image": "./media/b1.jpg"
      },
      {
        "title": "A wonderful weekend with Tenturi",
        "url": "http://a-publisher.com/tenturi",
        "image": "./media/b2.jpg"
      },
      ...
    ]
  }
}

Pages: amp-story-page

The <amp-story-page> component represents the content to display on a single page of a story.

Example

<amp-story-page id="cover">
  <amp-story-grid-layer template="fill">
    <amp-video layout="fill" src="background.mp4" poster="background.png" muted autoplay></amp-video>
  </amp-story-grid-layer>
  <amp-story-grid-layer template="vertical">
    <h1>These are the Top 5 World's Most...</h1>
    <p>Jon Bersch</p>
    <p>May 18</p>
  </amp-story-grid-layer>
  <amp-story-grid-layer template="thirds">
    <amp-img grid-area="bottom-third" src="a-logo.svg" width="64" height="64"></amp-img>
  </amp-story-grid-layer>
</amp-story-page>

Attributes

id [required]

A unique identifier for the page. Can be used for styling the page and its descendants in CSS, and is also used to uniquely identify the page in the URL fragment.

auto-advance-after [optional]

Specifies when to auto-advance to the next page. If omitted, the page will not automatically advance. The value for auto-advance-after must be either:

  • A positive amount of time to wait before automatically advancing to the next page
  • An ID of an HTMLMediaElement or video-interface video whose completion will trigger the auto-advance

For example:

<amp-story-page id="tokyo" auto-advance-after="1s">
background-audio [optional]

A URI to an audio file that plays while this page is in view.

For example:

<amp-story-page id="zurich" background-audio="./media/switzerland.mp3">

Children (of amp-story-page)

The <amp-story-page> component contains one or more layers. Layers are stacked bottom-up (the first layer specified in the DOM is at the bottom; the last layer specified in the DOM is at the top).

Layers: amp-story-grid-layer

Layers are stacked on top of one another to create the desired visual effect. The <amp-story-grid-layer> component lays its children out into a grid. Its implementation is based off of the CSS Grid Spec.

+ + =

Attributes

template [required]

The template attribute determines the layout of the grid layer. Available templates are described in the Templates section below.

grid-area [optional]

This attribute is specified on children of <amp-story-grid-layer>. grid-area specifies the named area (from using a template that defines them) in which the element containing this attribute should appear.

Example:

<amp-story-grid-layer template="thirds">
  <p grid-area="middle-third">Element 1</p>
  <p grid-area="lower-third">Element 2</p>
  <p grid-area="upper-third">Element 3</p>
</amp-story-grid-layer>

Templates

The following are available templates to specify for the layout of the grid layer.

fill

The fill template shows its first child full bleed. All other children are not shown.

Names Areas: (none)

Example:

<amp-story-grid-layer template="fill">
  <amp-img src="cat.jpg"></amp-img>
</amp-story-grid-layer>

vertical

The vertical template lays its elements out along the y-axis. By default, its elements are aligned to the top, and can take up the entirety of the screen along the x-axis.

Names Areas: (none)

<amp-story-grid-layer template="vertical">
  <p>Element 1</p>
  <p>Element 2</p>
  <p>Element 3</p>
</amp-story-grid-layer>

horizontal

The horizontal template lays its elements out along the x-axis. By default, its elements are aligned to the start of the line and can take up the entirety of the screen along the y-axis.

Names Areas: (none)

<amp-story-grid-layer template="horizontal">
  <p>Element 1</p>
  <p>Element 2</p>
  <p>Element 3</p>
</amp-story-grid-layer>

thirds

The thirds template divides the screen into three equally-sized rows, and allows you to slot content into each area.

Named Areas:

  • upper-third
  • middle-third
  • lower-third

<amp-story-grid-layer template="thirds">
  <p grid-area="middle-third">Element 1</p>
  <p grid-area="lower-third">Element 2</p>
  <p grid-area="upper-third">Element 3</p>
</amp-story-grid-layer>

Children (of amp-story-grid-layer)

An amp-story-grid-layer can contain any of the following elements:

Note: This list will be expanded over time.

Area Allowable tags
Media
  • <amp-audio>
  • <amp-gfycat>
  • <amp-google-vrview-image>
  • <amp-img>
  • <amp-video>
  • <source>
  • <track>
Analytics & Measurement
  • <amp-analytics>
  • <amp-experiment>
  • <amp-pixel>
Sectioning
  • <address>
  • <article>
  • <aside>
  • <footer>
  • <h1>-<h6>
  • <header>
  • <hgroup>
  • <nav>
  • <section>
Text
  • <abbr>
  • <amp-fit-text>
  • <amp-font>
  • <amp-gist>
  • <b>
  • <bdi>
  • <bdo>
  • <blockquote>
  • <br>
  • <cite>
  • <code>
  • <data>
  • <del>
  • <dfn>
  • <div>
  • <em>
  • <figcaption>
  • <figure>
  • <hr>
  • <i>
  • <ins>
  • <kbd>
  • <main>
  • <mark>
  • <p>
  • <pre>
  • <q>
  • <rp>
  • <rt>
  • <rtc>
  • <ruby>
  • <s>
  • <samp>
  • <small>
  • <span>
  • <strong>
  • <sub>
  • <sup>
  • <time>
  • <u>
  • <var>
  • <wbr>
Lists
  • <amp-list>
  • <amp-live-list>
  • <dd>
  • <dl>
  • <dt>
  • <li>
  • <ol>
  • <ul>
Tables
  • <caption>
  • <col>
  • <colgroup>
  • <table>
  • <tbody>
  • <td>
  • <tfoot>
  • <th>
  • <thead>
  • <tr>
Other
  • <amp-install-serviceworker>
  • <noscript>

Animations

Every element inside an <amp-story-page> can have an entrance animation.

You can configure animations by specifying a set of animation attributes on the element; no additional AMP extensions or configuration is needed.

Animation effects

The following animation effects are available as presets for AMP stories:

Preset name Default duration (ms) Default delay (ms)
drop 1600 0
fade-in 500 0
fly-in-bottom 500 0
fly-in-left 500 0
fly-in-right 500 0
fly-in-top 500 0
pulse 500 0
rotate-in-left 700 0
rotate-in-right 700 0
twirl-in 1000 0
whoosh-in-left 500 0
whoosh-in-right 500 0

Animation attributes

animate-in (required)

Use this attribute to specify the name of the entrance animation preset.

Example: A heading flies in from left of the page.

<h2 animate-in="fly-in-left">
Fly from left!
</h2>
animate-in-duration (optional)

Use this attribute to specify the duration of the entrance animation, in seconds or milliseconds (e.g., 0.2s or 200ms). The default duration depends on the animation preset you specified.

Example: A heading flies in from left of the page and the animation finishes within half a second.

<h2 animate-in="fly-in-left" animate-in-duration="0.5s" >
Fly from left!
</h2>
animate-in-delay (optional)

Use this attribute to specify the delay before starting the animation. The value must be greater than or equal to 0, in seconds or milliseconds (for example, 0.2s or 200ms). The default delay depends on the animation preset you specified.

Example: After 0.4 seconds, a heading flies in from the left of the page and completes its entrance within 0.5 seconds.

<h2 animate-in="fly-in-left"
    animate-in-duration="0.5s"
    animate-in-delay="0.4s">
Fly from left!
</h2>

animate-in-after (optional)

Use this attribute to chain or sequence animations (for example, animation2 starts after animation1 is complete). Specify the ID of the animated element that this element's animation will follow. The element must be present on the same <amp-story-page>. The delay is applied after the previous element's animation has finished. For further details, see the Sequencing animations section below.

For example, in the following code, object2 animates in after object1 completes their entrance:

<amp-story-page id="page1">
  <amp-story-grid-layer template="vertical">
    <div id="object1"
        animate-in="rotate-in-left">
        1
    </div>
    <div id="object2"
        animate-in="fly-in-right"
        animate-in-after="object1">
        2 <!-- will start after object1 has finished -->
    </div>
  </amp-story-grid-layer>
</amp-story-page>

Sequencing animations

To chain animations in sequence, use the animate-in-after attribute. All elements in a given chain must be present in the same <amp-story-page>. Elements without the animate-in-after attribute do not belong to a sequence chain, and will start independently on page entrance.

<amp-story-page id="my-sequencing-page">
  <amp-story-grid-layer template="vertical">
    <div class="circle"
        animate-in="drop-in"
        animate-in-duration="1.8s">
      1 <!-- will start independently -->
    </div>
    <div id="rotate-in-left-obj"
        class="square"
        animate-in="rotate-in-left"
        animate-in-after="fade-in-obj"
        animate-in-delay="0.2s">
      2 <!-- will start after fade-in-obj has finished -->
    </div>
    <div class="square"
        animate-in-after="rotate-in-left-obj"
        animate-in="whoosh-in-right"
        animate-in-delay="0.2s">
      3 <!-- will start after rotate-in-left-obj has finished -->
    </div>
    <div id="fade-in-obj"
        class="circle"
        animate-in="fade-in"
        animate-in-duration="2.2s">
      1 <!-- will start independently -->
    </div>
  </amp-story-grid-layer>
</amp-story-page>

Combining multiple animations

You can apply multiple entrance animations on one element (for example, an element flies into the page and fades in at the same time). It's not possible to assign more than one animation preset to a single element; however, elements with different entrance animations can be nested to combine them into one.

<div animate-in="fly-in-left">
   <div animate-in="fade-in">
     I will fly-in and fade-in!
   </div>
</div>

Validation

See amp-story rules in the AMP validator specification.