AMP

Triggering CSS animations & transitions

Important: this documentation is not applicable to your currently selected format stories!

CSS animations enable web elements to transition from one CSS style configuration to another. The browser can start defined animations on load, but event triggered CSS animations rely on adding and removing classes. AMP supports both animation types.

Use CSS when you have a smaller, contained animation that doesn't need to be precisely timed.

Defining CSS and keyframes

You can define CSS in AMP in the following ways:

  • Within the <style amp-custom> tag inside the head of the document. 75,000 byte limit.
  • Inline styles. Each instance of an inline style has a 1,000 byte limit. Inline styles count towards the 75,000 byte <style amp-custom> limit.
  • Within the <style amp-keyframes> tag inside the head of the document. 500,000 byte limit. Restricted to keyframe properties.

Read more in Style & layout about using CSS in AMP.

To keep your pages lean and speedy, AMP has enforced a 75,000 byte CSS limit in the <amp style-custom> tag. While you can use this to define animation styles, the 500,000 bye limit inside of <amp style-keyframes> tag allows for more verbose animations that won't take away precious site style resources.

  <style amp-custom>
    div {
      width: 100px;
      height: 100px;
      background: red;
      position: relative;
      animation: mymove 5s infinite;
    }
  </style>
</head>
<body>

<div></div>
  <style amp-keyframes>
   @keyframes mymove {
      0%   {transform: translatey(0px);}
      25%  {transform: translatey(200px);}
      75%  {transform: translatey(50px);}
      100% {transform: translatey(100px);}
    }
  </style>
</body>

Adding, removing, and toggling classes

The AMP action, toggleClass enables the addition and removal of classes to defined elements.

elementName.toggleClass(class="className")

You can toggle a class on the same element you'd like users to interact with, such as an animated hamburger menu.

 <div id="hamburger" tabindex=1 role=button on="tap:hamburger.toggleClass(class='close')">

The toggleClass action can apply to other elements as well and toggle between two classes by adding the force attribute.

<button on="tap:magicBox.toggleClass(class='invisible', force=true),magicBox.toggleClass(class='visible', force=false)">
  Disappear
</button>
<button on="tap:magicBox.toggleClass(class='visible', force=true),magicBox.toggleClass(class='invisible', force=false)">
  Reappear
</button>

If you need to remove a class and disallow reapplication, add the force attribute with a value of false. If you need to addd a class and disallow removal, add force with a value of true.

Animate with CSS and state

You can add and remove any number of CSS classes with states using amp-bind.

<head>
  <script async custom-element="amp-bind" src="https://cdn.ampproject.org/v0/amp-bind-0.1.js"></script>
  <style amp-custom>
    div {
      height: 100px;
      width: 100px;
      margin: 1em;
      background-color: green;
      margin-left: 100px;
      transition: 2s;
    }
    .visible {
      opacity: 1;
    }
    .invisible {
      opacity: 0;
    }
    .left {
      transform: translatex(-50px)
    }
    .right {
      transform: translatex(50px)
    }
    button {
      margin-top:  1rem;
      margin-left: 1rem;
    }
  </style>
</head>
<body>
  <amp-state id="magicBox">
    <script type="application/json">
      {
        "visibleBox": {
          "className": "visible"
        },
        "invisibleBox": {
          "className": "invisible"
        },
        "moveLeft": {
          "className": "left"
        },
        "moveRight": {
          "className": "right"
        }
      }
    </script>
  </amp-state>
  <div [class]="magicBox[animateBox].className"> </div>
  <button on="tap:AMP.setState({animateBox: 'invisibleBox'})">
    Disappear
  </button>
  <button on="tap:AMP.setState({animateBox: 'visibleBox'})">
    Reappear
  </button>
  <button on="tap:AMP.setState({animateBox: 'moveLeft'})">
    Move Left
  </button>
  <button on="tap:AMP.setState({animateBox: 'moveRight'})">
    Move Right
  </button>
</body>
Open this snippet in playground

Define multiple class animations by first adding a list of CSS classes within the <style amp-custom> tag in the head of the document:

    .visible {
      opacity: 1;
    }
    .invisible {
      opacity: 0;
    }
    .left {
      transform: translatex(-50px)
    }
    .right {
      transform: translatex(50px)
    }

Then pair each class with a state:

<amp-state id="magicBox">
  <script type="application/json">
    {
      "visibleBox": {
        "className": "visible"
      },
      "invisibleBox": {
        "className": "invisible"
      },
      "moveLeft": {
        "className": "left"
      },
      "moveRight": {
        "className": "right"
      }
    }
  </script>
</amp-state>

And link the element with the classes:

  <div [class]="magicBox[animateBox].className"> </div>

The states change from a linked AMP action or event. The following example changes the state from user interaction:

<button on="tap:AMP.setState({animateBox: 'invisibleBox'})">
    Disappear
</button>
<button on="tap:AMP.setState({animateBox: 'visibleBox'})">
    Reappear
</button>
<button on="tap:AMP.setState({animateBox: 'moveLeft'})">
    Move Left
</button>
<button on="tap:AMP.setState({animateBox: 'moveRight'})">
  Move Right
</button>

Using amp-bind in this way set the class explicitly to the defined class. You will not have to tell it to remove other classes.