Build a pure CSS animated slideshow in an email

Heidi Olsen
Nov 18, 2015 · 4 min read



While brainstorming ideas for our eROI Welcome Series emails, we wanted to create an experience that felt conversational and fresh. We tried and tested a few different ideas utilizing CSS animation and found that a pure CSS slideshow would be a perfect fit.

The beauty of implementing a CSS slideshow in your email is that it has a graceful fallback. This is an important factor when considering which technologies to leverage in your email. When deciding on whether or not to incorporate a CSS slideshow into your next email marketing campaign, here are a few things to consider:

  • If the majority of your subscribers use newer clients like Apple Mail and WebKit-supported clients, then CSS animation may be a good option. To find out what clients your subscribers are using, include a Litmus tracking pixel in your email or add Google Analytics tracking strings to your outbound links. According to the Email Market Share report about half of all subscribers are using a Webkit-supported client.
  • WebKit Support in Email Clients include Apple Mail, iOS (iPhone / iPad), Android Mail 2.3, Android Mail 4.2, AOL Mail (Chrome), and Outlook 2011 + 2015 (Mac)
  • In clients that do not support CSS animation, the “slides” stack on top of each other. I would recommend allowing the slideshow to scale full-width instead of adding it into a column-based layout.
  • In our live testing, we’ve found that any animation that is delayed longer than 10 seconds will time out on mobile devices. This is most likely due to data usage. Because of this you want to make sure you are only cycling through a few pieces of content.
  • The demo here does not include navigation, so be mindful to keep the content concise so the reader can digest the information before the next slide appears.




To begin, create separate tables for each slide. Each table should have minimum height, a background color, a universal CSS class and a unique CSS id:

<table width=”100%” cellpadding=”0" cellspacing=”0" border=”0" align=”center” class=”fadeIn” id=”tableAnimate1" style=”min-height:500px; bgcolor=”#FFFFFF”>
<td valign=”top”>SLIDE CONTENT</td>

Create a main table to hold your three tables with the same minimum height, a position of relative and a “wrapper-table” class:

<table width=”100%” align=”center” cellpadding=”0" cellspacing=”0" border=”0" style=”position:relative; min-height:500px;” class=”wrapper-table”>
<td valign=”top”>STACK SLIDE TABLES HERE</td>


Create the following media-query:

@media screen and (-webkit-min-device-pixel-ratio: 0) { /*INSERT ALL CSS ANIMATION STYLES HERE */ }

By using a WebKit-specific media query, it will only enable the animation in WebKit-supported clients. This allows for a graceful fallback and makes it easier to avoid some wonkiness in clients that do not support CSS animation.

Next you will set up the keyframe animations. If you have not used keyframes before, it is important to include the prefixes -webkit-, -moz- for full support. For more robust CSS Animations, I would recommend using a “postprocessor” for handling vendor prefixes in CSS. Autoprefixer is a great tool that will parse your CSS and add the vendor prefixes automagically, saving you some time and headache.

The following code specifies the CSS styles inside the @keyframes rule and allows the animation to gradually change from the current style to the new style at certain times.

@keyframes fadeIn {
25% { opacity: 1; }
75% { opacity: 0; }
-moz-keyframes fadeIn {
25% { opacity: 1; }
75% { opacity: 0; }
@-webkit-keyframes fadeIn {
25% { opacity: 1; }
75% { opacity: 0; }

To get an animation to work, you must bind the animation to an element. The following binds the “fadeIn” animation to the “fadeIn” CSS class:

.fadeIn {
position: absolute;
-webkit-animation:fadeIn 15s infinite;
-moz-animation:fadeIn 15s infinite;
animation:fadeIn 15s infinite;
opacity: 0;

Next, you will delay the animation for each slide. Let’s say you gave your first table an ID of “tableAnimate1″. You would give it the following properties: #tableAnimate1 { -webkit-animation-delay: 0s; -moz-animation-delay: 0s; animation-delay: 0s; }Because this is the first slide in the slideshow, there is no delay. The following code will make the second and third table animate after in 5 second intervals:#tableAnimate2 { -webkit-animation-delay: 5s; -moz-animation-delay: 5s; animation-delay: 5s; }#tableAnimate3 { -webkit-animation-delay: 10s; -moz-animation-delay: 10s; animation-delay: 10s; }

The rise of email opens on mobile make it an exciting time to be an email marketer. We are finally able to embrace the technologies our web counterparts have been able to utilize freely for many, many years. However just because you can, doesn’t mean you should. Animation should be used to inspire, inform and instruct. If the animation doesn’t help support your messaging, save it for another email so the effect doesn’t become lackluster.


Feel free to reach out to me at heidi [at] or tweet at @swisswebmiss. If you want to contribute to this project, please check out our repository on GitHub.

[Originally published on]

Heidi Olsen

Written by

Senior Developer by day, Fun Professional by night

Welcome to a place where words matter. On Medium, smart voices and original ideas take center stage - with no ads in sight. Watch
Follow all the topics you care about, and we’ll deliver the best stories for you to your homepage and inbox. Explore
Get unlimited access to the best stories on Medium — and support writers while you’re at it. Just $5/month. Upgrade