www.emailonacid.com Open in urlscan Pro
52.11.154.122  Public Scan

URL: https://www.emailonacid.com/blog/article/email-development/tutorial-animated-image-carousel-for-email/
Submission: On December 02 via api from IE — Scanned from DE

Form analysis 2 forms found in the DOM

GET https://www.emailonacid.com

<form action="https://www.emailonacid.com" method="get"><label class="screen-reader-text" for="cat">Categories</label><select name="cat" id="cat" class="postform">
    <option value="-1">Select Category</option>
    <option class="level-0" value="173">Email Development</option>
    <option class="level-0" value="199">Email Marketing</option>
    <option class="level-0" value="172">EOA News</option>
    <option class="level-0" value="5381">Featured White Paper</option>
    <option class="level-0" value="2">Industry News</option>
    <option class="level-0" value="219">Reporting</option>
    <option class="level-0" value="8446">Splat Chat</option>
    <option class="level-0" value="208">Tutorial</option>
    <option class="level-0" value="5429">White Papers</option>
  </select>
</form>

POST https://forms.hsforms.com/submissions/v3/public/submit/formsnext/multipart/2284985/878777d7-16f5-4157-9a56-c4e24e6d7403

<form novalidate="" accept-charset="UTF-8" action="https://forms.hsforms.com/submissions/v3/public/submit/formsnext/multipart/2284985/878777d7-16f5-4157-9a56-c4e24e6d7403" enctype="multipart/form-data" id="hsForm_878777d7-16f5-4157-9a56-c4e24e6d7403"
  method="POST" class="hs-form stacked hs-form-private hsForm_878777d7-16f5-4157-9a56-c4e24e6d7403 hs-form-878777d7-16f5-4157-9a56-c4e24e6d7403 hs-form-878777d7-16f5-4157-9a56-c4e24e6d7403_a80826f1-e5b3-4ff7-986b-0989fdbec2d3"
  data-form-id="878777d7-16f5-4157-9a56-c4e24e6d7403" data-portal-id="2284985" target="target_iframe_878777d7-16f5-4157-9a56-c4e24e6d7403" data-reactid=".hbspt-forms-0">
  <div class="hs-dependent-field" data-reactid=".hbspt-forms-0.1:$0">
    <div class="hs_email hs-email hs-fieldtype-text field hs-form-field" data-reactid=".hbspt-forms-0.1:$0.$email"><label id="label-email-878777d7-16f5-4157-9a56-c4e24e6d7403" class="" placeholder="Enter your Email"
        for="email-878777d7-16f5-4157-9a56-c4e24e6d7403" data-reactid=".hbspt-forms-0.1:$0.$email.0"><span data-reactid=".hbspt-forms-0.1:$0.$email.0.0">Email</span><span class="hs-form-required"
          data-reactid=".hbspt-forms-0.1:$0.$email.0.1">*</span></label>
      <legend class="hs-field-desc" style="display:none;" data-reactid=".hbspt-forms-0.1:$0.$email.1"></legend>
      <div class="input" data-reactid=".hbspt-forms-0.1:$0.$email.$email"><input id="email-878777d7-16f5-4157-9a56-c4e24e6d7403" class="hs-input" type="email" name="email" required="" placeholder="Email Address *" value="" autocomplete="email"
          data-reactid=".hbspt-forms-0.1:$0.$email.$email.0" inputmode="email"></div>
    </div>
  </div>
  <div class="hs_lead_generation hs-lead_generation hs-fieldtype-select field hs-form-field" style="display:none;" data-reactid=".hbspt-forms-0.1:$1"><label id="label-lead_generation-878777d7-16f5-4157-9a56-c4e24e6d7403" class=""
      placeholder="Enter your lead generation" for="lead_generation-878777d7-16f5-4157-9a56-c4e24e6d7403" data-reactid=".hbspt-forms-0.1:$1.0"><span data-reactid=".hbspt-forms-0.1:$1.0.0">lead generation</span></label>
    <legend class="hs-field-desc" style="display:none;" data-reactid=".hbspt-forms-0.1:$1.1"></legend>
    <div class="input" data-reactid=".hbspt-forms-0.1:$1.$lead_generation"><input name="lead_generation" class="hs-input" type="hidden" value="blog_in" data-reactid=".hbspt-forms-0.1:$1.$lead_generation.0"></div>
  </div><noscript data-reactid=".hbspt-forms-0.2"></noscript>
  <div class="hs_submit hs-submit" data-reactid=".hbspt-forms-0.5">
    <div class="hs-field-desc" style="display:none;" data-reactid=".hbspt-forms-0.5.0"></div>
    <div class="actions" data-reactid=".hbspt-forms-0.5.1"><input type="submit" value="Submit" class="hs-button primary large" data-reactid=".hbspt-forms-0.5.1.0"></div>
  </div><noscript data-reactid=".hbspt-forms-0.6"></noscript><input name="hs_context" type="hidden"
    value="{&quot;rumScriptExecuteTime&quot;:2325.7999954223633,&quot;rumServiceResponseTime&quot;:2811.400001525879,&quot;rumFormRenderTime&quot;:2.600006103515625,&quot;rumTotalRenderTime&quot;:2814.900001525879,&quot;rumTotalRequestTime&quot;:483.9000015258789,&quot;lang&quot;:&quot;en&quot;,&quot;embedAtTimestamp&quot;:&quot;1638454499670&quot;,&quot;formDefinitionUpdatedAt&quot;:&quot;1616765144742&quot;,&quot;pageUrl&quot;:&quot;https://www.emailonacid.com/blog/article/email-development/tutorial-animated-image-carousel-for-email/&quot;,&quot;pageTitle&quot;:&quot;Animated Image Carousel for Email Part 1 | Email On Acid&quot;,&quot;source&quot;:&quot;FormsNext-static-5.415&quot;,&quot;sourceName&quot;:&quot;FormsNext&quot;,&quot;sourceVersion&quot;:&quot;5.415&quot;,&quot;sourceVersionMajor&quot;:&quot;5&quot;,&quot;sourceVersionMinor&quot;:&quot;415&quot;,&quot;timestamp&quot;:1638454499673,&quot;userAgent&quot;:&quot;Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/96.0.4664.45 Safari/537.36&quot;,&quot;originalEmbedContext&quot;:{&quot;portalId&quot;:&quot;2284985&quot;,&quot;formId&quot;:&quot;878777d7-16f5-4157-9a56-c4e24e6d7403&quot;,&quot;target&quot;:&quot;#hbspt-form-1638454498919-5894312012&quot;},&quot;renderedFieldsIds&quot;:[&quot;email&quot;],&quot;formTarget&quot;:&quot;#hbspt-form-1638454498919-5894312012&quot;,&quot;correlationId&quot;:&quot;72e45527-2169-4930-a589-4b865fd46a6b&quot;,&quot;hutk&quot;:&quot;fc1bd62f077208cbbe9c3e062ce81d85&quot;,&quot;captchaStatus&quot;:&quot;NOT_APPLICABLE&quot;}"
    data-reactid=".hbspt-forms-0.7"><iframe name="target_iframe_878777d7-16f5-4157-9a56-c4e24e6d7403" style="display:none;" data-reactid=".hbspt-forms-0.8"></iframe>
</form>

Text Content

This website stores cookies on your computer. These cookies are used to improve
your website experience and provide more personalized services to you, both on
this website and through other media. To find out more about the cookies we use,
see our Privacy Policy.

We won't track your information when you visit our site. But in order to comply
with your preferences, we'll have to use just one tiny cookie so that you're not
asked to make this choice again.

Accept Decline
 * Features
   * Overview
   * Content Checks
   * Inbox Display
   * Email Accessibility
   * Image Validation
   * Links
   * Spelling
   * Deliverability
   * Email Deliverability
   * Previews
   * Email Testing
   * Email Team Management
 * Pricing
 * Solutions
   * Overview
   * Enterprise Solutions
   * White Label Previews
   * White Label Analytics
 * Resources
   * Resource Library
   * Partner Opportunities
   * Case Studies
   * White Papers
   * Help Center
   * Splat Fest
   * Events
 * Blog
 * Get a Demo

Free Trial  Login Sign Up for a Demo Login Free Trial
Blog   /   Tutorial: Animated Image Carousel for Email – Part 1
Email Development September 30, 2016


TUTORIAL: ANIMATED IMAGE CAROUSEL FOR EMAIL – PART 1

14

--------------------------------------------------------------------------------

This is the first part of a multi-part tutorial series on how to create an
animated image carousel that works in email clients that support CSS animation.
This article will cover how to build a basic carousel that will fade from one
image to the next.

Since CSS animations mostly only work in Webkit based clients, the carousel will
be active in iOS Mail (iPhone, iPad), Apple Mail and Outlook for iOS and Mac.
Other clients will display the fallback content.

Subsequent articles will add effects such as pan and zooming and sliding. So
stay tuned. If you’re new to CSS animations, check out this helpful primer by
Alex Ilhan.


THREE IMAGE CAROUSEL

The carousel we’ll be building will contain three images, although you should be
able to customize it for as many images as you like.



View completed demo (Use Chrome or Safari to see the animation)

The basics of this carousel are pretty straightforward; we start with a div
containing a set of images with links.

<div class="carousel" style="position:relative;width:500px;height:320px;">
  <a href="https://www.google.com/search?q=castles"><img src="https://freshinbox.com/examples/animated-carousel/images/car-castle.jpg" border="0"></a>
  <a href="https://www.google.com/search?q=meadows"><img src="https://freshinbox.com/examples/animated-carousel/images/car-meadow.jpg" border="0"></a>
  <a href="https://www.google.com/search?q=coast"><img src="https://freshinbox.com/examples/animated-carousel/images/car-coast.jpg" border="0"></a>
</div>

Then we’re going position the images so they overlap each other using absolute
positioning. This will display the last image on top instead of the first. We’ll
change that in a minute.

<style>
  .carousel a{
    position:absolute;
    top:0px;
    left:0px; 
  }
</style>

SWAPPING THE IMAGES USING Z-INDEX

We’ll now use the following CSS to cycle through the images in the carousel.
Specifically, we’ll shift their z-index positions up and down depending on which
part of the animation the image is in.

  .carousel a {
    position:absolute;
    top:0px;
    left:0px; 
    -webkit-animation: car-anim 9s linear infinite;    
  }

  .carousel a:nth-child(1){
    -webkit-animation-delay: 0s;    
  }
  .carousel a:nth-child(2){
    -webkit-animation-delay: 3s;    
  }
  .carousel a:nth-child(3){
    -webkit-animation-delay: 6s;    
  }

  @-webkit-keyframes car-anim 
  {
      0% {
        z-index:2;
      }
      33%{
        z-index:2;
      }
      33.001%{
        z-index:1;
      }
      100%{
        z-index:1;
      }
  }

See an example here

As you can see, we have an animation sequence called car-anim. All three images
will be sharing the same animation, but they’ll start at different times using
the animation-delay property. The animation will last a total of 9 seconds (3
seconds for each image).

So far, pretty straightforward stuff.

FIXING SWAPPING GLITCH

If you run the code above, you’ll note that at times there’s what appears like a
very brief glitch when the images swap. This is due to the fact that when
cycling the images, the lower level images share the same z-index (1). In
absolute position stacked elements, if two elements share the same z-index the
bottom-most element appears on top — therefore there’s a brief moment where the
3rd image appears before the 2nd image gets its z-index changed to 2.

This issue doesn’t present itself if we cycle the images according to their
natural stacking order, (from the 3rd image to the 1st), but I felt conceptually
cycling the 3rd image first feels odd, so we fix it by hiding an image using
opacity:0 when it is no longer at the top. I add a slight delay when hiding to
account for the iOS transition gap.

  @-webkit-keyframes car-anim
  {
      0% {
        z-index:2;
        opacity:1;
      }
      33%{
        z-index:2;
      }
      33.1%{
        z-index:1;
        opacity:1;
      }
      35%{
        opacity:0;
      }
      100%{
        z-index:1;
        opacity:0;
      }
  }

USING NEGATIVE ANIMATION DELAY TO ADDRESS IOS SCROLL QUIRK

In iOS9 the email client pauses animations when the user scrolls the email.
However, it does not pause the animation delay timer. This can potentially cause
timing issues if the user scrolls the email after the first animation has
started but the animations for other images have yet to start. This issue is not
present in iOS10.

One solution is to not use animation delay, but that would be a huge setback.
Thankfully, there’s another option, and that is to use negative animation
delays. Negative animation delays as stated in the referenced article “start the
animation immediately, as if that amount of time has already gone by.” This
works for us because any scrolling of the email will pause all animations since
they are already running so the animations don’t lose sync.

We change our animation delays for our images to the following. You can shift
the delays up or down to start the animation at any time but they must be spaced
equally apart based on the total animation runtime.

  .carousel a:nth-child(1){
    -webkit-animation-delay: -9s;    
  }
  .carousel a:nth-child(2){
    -webkit-animation-delay: -6s;    
  }
  .carousel a:nth-child(3){
    -webkit-animation-delay: -3s;    
  }

FADE EFFECT

To improve the carousel experience we’ll add a fade effect so that the images
fade out and fade in during the image transition. This is achieved using the
opacity style. For our purpose we’ll set the transition period to 5%. You can
set it to a larger or smaller value to speed up or shorten the transition time.

@-webkit-keyframes car-anim
  {
      /* start fade in */
      0%{
        z-index:2;
        opacity:0;
      }
      /* end fade in */
      5%{
        opacity:1;
      }
      33%{
        z-index:2;
      }
      /* lower z-index - allow next image to fade in */
      33.1%{
        z-index:1;
      }
      /* already obscured */
      38%{
        opacity:1;
      }
      /* hide */
      38.1%{
        opacity:0;
      }
      100%{
        z-index:1;
        opacity:0;
      }
  }

The code above will start the animation as the first frame is fading in (the
last frame fading out). Since we don’t want to start the animation in the middle
of a transition, we push out the animation delay by one second:

  .carousel a:nth-child(1){
    -webkit-animation-delay: -10s;    
  }
  .carousel a:nth-child(2){
    -webkit-animation-delay: -7s;    
  }
  .carousel a:nth-child(3){
    -webkit-animation-delay: -4s;    
  }

ADD RESPONSIVENESS

To make the carousel scale to the width of its container, we add the following
CSS.

  .carousel{
    width:100% !important;
    height:auto !important;
  }

  .carousel a{
    width:100%;
    display:block;
  }  

  .carousel img{
    display:block!important;
    width:100% !important;
    height:auto !important;
  }

We also need to make at least one image position:relative so that the fluid
container doesn’t collapse now that height is set to auto.

  .carousel a:nth-child(1){
    position:relative;
  }


FALLBACKS AND CUSTOMIZATION

I’ll cover a fallback technique for clients that can’t show the carousel, as
well as some details about how to customize this example for your needs.

HANDLING CLIENTS WITHOUT CSS ANIMATION SUPPORT

At this point, our “best case scenario” animated carousel is done. Now we need
to ensure that clients that don’t support animation don’t get a broken
experience. There are multiple ways to handle “fallback content” and this
article goes into the various options.

The strategy I’ll use for this example is to hide the carousel and display a
separate “fallback” block for clients that don’t support CSS animation. To do
this, we display the fallback content by default and then in a
-webkit-min-device-pixel-ratio media query we hide the fallback content and
display the carousel. This is because Webkit based email clients support CSS
animation.

Here’s how it looks.

<style>
@media screen and (-webkit-min-device-pixel-ratio: 0) {
    .fallback{
    display:none;
  }
  .carousel{
    display:block !important;
    max-height:none !important;
    position:relative;
  }
  … other CSS animation code ...
}
</style>
<!--[if !mso]><!-- -->
<div class="carousel" style="overflow:hidden;display:none;max-height:0px;">
   Carousel content
</div>
<!--<![endif]-->
<div class="fallback">
   Fallback content
</div>

We also need to hide the carousel from the Zimbra email client (Comcast) and
Samsung email client which, although responsive to the
-webkit-min-device-pixel-ratio media query, lack the ability to fully render the
carousel.

  #MessageViewBody .fallback,
  body.MsgBody .fallback{ 
    display:block; 
  }
  #MessageViewBody .carousel,
  body.MsgBody .carousel{
    display:none !important;
  }

MORE IMAGES?

If you’d like to have more than 3 images in your carousel, simply add more
images into the HTML and adjust your animation blocks appropriately. For four
images, instead of fading out at 33%, you fade out at 25% and for five images,
you fade out at 20%.

BACKGROUND IMAGE APPROACH

There’s an amazingly simple approach to swap images in a carousel by changing
the URL of background images. Unfortunately, this technique has a side effect in
iOS9 that causes the images to glow and fade even when the images are not
transitioning. If you’re interested, you can see the code for it here.
Apparently iOS10 does not suffer from this bug so this may be an option soon.


FINISHED CODE

So there you have it, a fully working responsive animated image carousel!

Check out the completed code. (Use Chrome or Safari to see the animation)


ALL TUTORIALS IN THIS SERIES

Animated Image Carousel for Email

Animated Image Carousel for Email with Ken Burns Effects

Animated Image Carousel for Email with Sliding Transitions

Implementing Navigation Controls in Image Carousels for Email


TEST WITH EMAIL ON ACID

In the coming weeks there will be more articles that build upon this example, so
stay tuned!

When attempting complex email techniques like this one, it’s best to test your
code and make sure it’s looking great everywhere. Try email testing free for a
week and see what you think!

 * 
 * 
 * 
 * 



AUTHOR: ALEX ILHAN

Hailing all the way from England, Alex brings his email development expertise
along with an endless stream of cups of tea and British cynicism. Follow him on
Twitter: @omgitsonlyalex.

AUTHOR: ALEX ILHAN

Hailing all the way from England, Alex brings his email development expertise
along with an endless stream of cups of tea and British cynicism. Follow him on
Twitter: @omgitsonlyalex.


14 THOUGHTS ON “TUTORIAL: ANIMATED IMAGE CAROUSEL FOR EMAIL – PART 1”

 1.  Paeon says:
     October 4, 2016 at 3:34 pm
     
     Hi, which clients does this work on? And why is this better than a simple
     animated gif slideshow?

     
 2.  Gordon says:
     October 4, 2016 at 4:26 pm
     
     Hi Paeon,
     
     As stated, it works in most webkit browsers and in the default Apple Mail
     client. The advantage is that GIFs can be very heavy in terms of image
     size, where as 2 images animated using CSS should use considerably less
     space. Also, you can add individual links to each image whereas when it’s a
     GIF you can only link the asset once.
     
     I’ve just built this from the tutorial, it’s been a great help and works as
     expected!
     
     So I hope I answered your question Paeon and Thank you Justin Khoo for
     writing this post!
     
     Thanks,
     G
     
     http://www.meowplates.co.uk

     
 3.  Diego says:
     October 4, 2016 at 4:57 pm
     
     Hi!,
     
     It is possible to make a carrousel with another kind of transition, like
     slide on the X and Y axis.
     
     Thanks!

     
 4.  Justin Khoo says:
     October 5, 2016 at 1:05 am
     
     @Paeon you can also implement smooth transitions using CSS and animations
     offer better color fidelity (animated gif has a 256 color limit)
     
     @Gordon thank you for your comments and I’m glad you’ve put it to the test!
     
     @Diego keep a look out for a follow up article 😉

     
 5.  hill2001 says:
     November 4, 2016 at 3:15 pm
     
     Strange, I only see the animation on mobile. What am I doing wrong? Thanks!

     
 6.  hill2001 says:
     November 5, 2016 at 2:47 pm
     
     Ah my media tag is prevented the animation in a browser > @media screen and
     (max-width: 480px) {
     
     Any ideas how to integrate the 480px max-width into the animation script?

     
 7.  hill2001 says:
     November 5, 2016 at 2:58 pm
     
     Got it! Thanks again for this fantastic script!

     
 8.  Marjolein says:
     April 4, 2017 at 2:21 pm
     
     I’m trying to add more images to the carousel, but I can’t seem to get the
     delay and the length of the animation to match correctly. I have 6 images
     in total, with delays from -19s til -4s for the last. The length of the
     animation is 18s now, as I figured your longest delay was -10s and the
     length of the animation was 9s. But it’s either showing the last images too
     long before finally showing the first and looping through the images or if
     I shorten the animation it shows the last image for a second before
     changing to the first, but then it seems to skip 2 and 3.
     
     How do I calculate the length of the animation needed to fix all 6 images
     in the animation?
     
     Thanks!

     
 9.  Justin Khoo says:
     April 20, 2017 at 10:28 pm
     
     Hi @Marjolein
     
     Sorry it has taken me a while to get back to you, but I’ve posted an
     example with 6 images here:
     
     https://codepen.io/freshinbox/pen/QvNqoo

     
 10. Fransjo says:
     May 16, 2017 at 8:19 am
     
     Hi .. great example !! I’m trying to do only 2 images (fadein) .. so I
     removed the third image, but now I get a blanc space after the 2nd image.
     What must I alter so with 2 images it will transition back to image 1?

     
 11. Amily C says:
     June 8, 2017 at 3:35 pm
     
     Hi there,
     
     Trying to get the desktop version to work… with no results.
     I got this in my CSS: @media screen and (max-width: 480px) {
     Any chance you can help?
     
     Thanks
     Amily

     
 12. EC says:
     December 13, 2018 at 8:35 pm
     
     Hi there,
     
     I have been doing some testing with the carousel which is look great so
     thanks for tutorial, however I appear to be having an issue in Outlook
     Email App on IOS11 where the slides stack instead of showing the carousel
     or fallback – has anyone else came across this issue & any advise how to
     fix? Thanks in advance 🙂
     
     Thanks
     EC

     
 13. DVH says:
     December 14, 2018 at 4:10 pm
     
     Hi,
     
     I’m having the same issue as EC, it stacks in Outlook iOS. If anyone knows
     a fix, please let me know! Thanks.
     
     DVH

     
 14. Jessa Moon says:
     March 7, 2019 at 12:59 pm
     
     I’m running into the stacking issue in Outlook iOS and Outlook for Android.
     Would love to know if anyone has a solution.

     

Comments are closed.


CATEGORIES

Categories Select Category Email Development Email Marketing EOA News Featured
White Paper Industry News Reporting Splat Chat Tutorial White Papers


LATEST ARTICLES

Email Marketing December 2, 2021

EMAIL AND B2B CONTENT MARKETING IN 2022

Email Marketing November 29, 2021

ACCESSIBLE HOLIDAY EMAILS AND COLOR BLINDNESS

Email Development November 24, 2021

HOW TO USE MEDIA QUERIES IN HTML EMAILS

LEARN MORE

 * Pricing
 * Features
 * Enterprise Solutions
 * White Label Previews
 * Security

COMPANY

 * Company
 * Careers
 * News
 * Partnerships
 * Customer Feedback

HELP

 * Help Center
 * Contact
 * Custom Demo
 * Blog

Subscribe to our Emails:

Email*

lead generation


 * 
 * 
   
 * 
 * 

Terms and Conditions | Privacy Policy | CCPA | © 2021 Email On Acid|Denver, CO

[if lte IE 8]
[if lte IE 8]
Close GDPR Cookie Settings
 * Privacy Overview
 * Strictly Necessary Cookies

Powered by  GDPR Cookie Compliance
Privacy Overview

This website uses cookies so that we can provide you with the best user
experience possible. Cookie information is stored in your browser and performs
functions such as recognizing you when you return to our website and helping our
team to understand which sections of the website you find most interesting and
useful. We also use cookies to assist in marketing and advertising efforts to
provide you with useful information related to our products and services.

You can adjust all of your cookie settings through your browser settings.

Strictly Necessary Cookies

Strictly Necessary Cookie should be enabled at all times so that we can save
your preferences for cookie settings.

Enable or Disable Cookies

If you disable this cookie, we will not be able to save your preferences. This
means that every time you visit this website you will need to enable or disable
cookies again.

Enable All Save Settings