Start and Pause CSS Animation

How to Restart CSS Animations in Email Using The :active Pseudo-class


This article shows you a technique to restart CSS animations with a single click or tap using the :active pseudo-class. There are two kinds of CSS animations, those that only run once, and those than run continuously. Some CSS animations that run in loops may be distracting to the recipient of your email so you might only want to run an animation once. However, it would be useful if the recipient were given an option to replay the animation on demand. Although the CSS animation-play-state property supports paused and running, it there is no property that makes the animation "restart". On the web, restarting animations commonly involve the use of Javascript. Unfortunately we don't have such a luxury with email. Thankfully there's a simple technique to restart CSS animations that works in email clients. My code snippets use the -webkit prefix. This is because for the most part animations only work in Webkit based clients.

Using the :active pseudo-class

The key to restarting a CSS animation is to set the animation-name of an animation to 'none' and then setting it back to the original animation. As you can see this requires two steps. One to switch it to a different animation and one to set it back. You need a mechanism that can toggle these states in one action. Although checkboxes can be used to toggle between two states, if you used a checkbox you'd need to tap twice. We have two pseudo-classes that fit our needs: :hover and :active. Both of these selectors only operate either while the cursor is over an element or when the user is clicking on an element. Since our goal is to restart an animation when the user clicks on a "restart" button, the :active pseudo-class is preferred. Here's the code to play an animation:
<style>
.box{
  -webkit-animation: launch 2s; 
}
@-webkit-keyframes launch{
  from {
    transform:translateX(0px);
  }
  to{
    transform:translateX(250px);
  }
}
</style>
<a href="#r" id="replay">replay animation</a>
<div class="anim-container">
<div class="box"></div>
</div>
In our example, we set the animation property to none when a user is clicking on the "replay" button. When the user releases the button, the :active selector becomes inactive and the animation reverts back to the original animation, thus restarting the animation.
#replay:active + .anim-container .box{
  -webkit-animation-name:none!important;
}
View code example

Support for :active in email clients

Interestingly :active has a wide support among Webkit based email clients including iOS. The peculiar thing about iOS is that the :active selector only fires briefly when an element is tapped. Unlike on a browser, where the :active selector stays active as long as the element in clicked, in iOS tapping and holding a button will not prolong the :active selector. That's why for the longest time, there was very little value in using the :active selector in interactive email. However, for the purpose of restarting animations, this brief firing of the selector is perfect!

Outlook for iOS quirk

Outlook on iOS has a quirk where clicking on a link with a named anchor will cause Outlook to launch the web browser. One method to address the Outlook on iOS quirk is to quickly move the element away when the :active selector is fired preventing the actual link from firing and opening the browser. This can be done by using the CSS translate transform to move the element 1000px to the left when the :active selector is fired. Note CSS transforms can only be applied to block level elements.
#replay:active{
  transform:translateX(-1000px);
}
Alternatively, you can use an image as the trigger instead. The default iOS Mail client will only fire the :hover or :active selectors when applied to links, images or labels.

Arrangement of elements

As you've probably noticed, this technique requires that the replay trigger is placed before the animated element in the code, since the sibling selector can only target elements that are ahead and not behind itself. What if you want to place the trigger after the animated element? The simplest way to achieve that is to either use absolute positioning or CSS transforms to visually place your trigger after the animated element on the email. (Keep in mind the Samsung Android client does not support absolute positioning). View code example

Starting animations manually

Sometimes you don't want an animation to automatically start. This can be done by using the :checked state using a label that targets a radio element. Clicking the label the first time will activate the :checked state of the radio element causing the animation to run once. By targeting the label using the :active selector, clicking the label again will cause the animation state to switch and switch back, and thus restarting the animation.
<style>
#cbox:checked + .anim-container .box{
  -webkit-animation: launch 2s; 
}
#replay:active + .box{
  -webkit-animation-name: none!important;
}
</style>

<input type="radio" id="cbox">
<div class="anim-container">
  <label for="cbox" id="replay">play animation</label>
  <div class="box"></div>
</div>
Playing CSS animations View code example Keep in mind that email clients such as Outlook on iOS and Mac (and certain email service providers like MailChimp) do not support form elements in email, so you won't be able to apply this trick. Make sure you hide the checkboxes in your email. Here's an article that goes into the details of hiding form elements.

Examples

View email example A cool use of a replay button is to allow the recipient to replay an intro animation in an email. Here's an email that plays fireworks with a recipient opens the email. The replay button allows the recipient to enjoy the fireworks as many times without having to reopen the email. Another use of a replay button is to play animations that may be embedded further down the email content (below the fold), by having a replay button recipients will be able to start the animation when they are ready to view the animation.

Fallbacks

When working with interactivity and animations in email, you need to ensure the experience on less capable clients are not negatively impacted, so be sure to plan for those clients as well. This article goes into how you can display fallback content for clients that don't support these features. Testing on the multitudes of email clients is where Email on Acid can save you a ton of time. Get over 70 previews in just one minute by testing with Email on Acid.