Creating html5 & css3 Slideshows - Part 2

Creating html5 & css3 Slideshows
with pseudo selector :nth-of-type & CSS animation property

Part 2.   Cross Fade Animation using :nth-of-type Pseudo Class

When creating a Cross Fade Slideshow, the HTML mark-up can be designed to stack the images using multiple <img> tags, or using <div></div> tags to hold those images as background-images.  The resulting mark-up for a 6 image slideshow is either of:-

<div id="x-fade">
   <img src="img-1.jpg" alt="slide-1">
   <img src="img-2.jpg" alt="slide-2">
   <img src="img-3.jpg" alt="slide-3">
   <img src="img-4.jpg" alt="slide-4">
   <img src="img-5.jpg" alt="slide-5">
   <img src="img-6.jpg" alt="slide-6">
</div>
<div id="x-fade">
   <div></div>
   <div></div>
   <div></div>
   <div></div>
   <div></div>
   <div></div>
</div>

Its fairly obvious that the <div> method on the right is the simplest, involving the least mark-up, and the slideshow itself will be completely controlled via the CSS.

The following CSS is the basic requirement for a cross-fading slideshow, and starts with styles relating to the #x-fade (the outer holding div), setting the dimensions, followed by the #x-fade div (common styles for the 6 inner divs), which similarly provides all the basic information pertaining to the 6 divs which form the actual cross-fading sideshow.  You will note that other than the containing <div id="x-fade">, there is no mark-up to identify any other <div>, and this is where the CSS pseudo element selector of :nth-of-type() comes into play.  Each of the 6 divs will be used to display a background-image, and each div is identified as follows:-

#x-fade { /* the outer holding div */
   font-family: arial, sans-serif;
   font-size:1.2em;
   position: relative;
   width: 854px;
   height: 289px;
   margin: 0 auto;
   margin-top:180px;
   }
#x-fade div  { /* each of the inner 6 divs */
   position: absolute;
   left: 0;
   top: 0;
   width: 854px;
   height: 289px;
   background-repeat: no-repeat;
   }
#x-fade:hover div { /* optional */
   animation-play-state: paused;
   }
#x-fade div {
   animation-name: xFade; /* matches @keyframes name */
   animation-duration: 48s;
   animation-timing-function: ease-in-out;
   animation-iteration-count: infinite;
   }
#x-fade div:nth-of-type(1) { /* img urls & sequential delays */
   background-image: url('images/rs-079.jpg');
   animation-delay: 40s;
   }
#x-fade div:nth-of-type(2) {
   background-image: url('images/rs-018.jpg');
   animation-delay: 32s;
   }
#x-fade div:nth-of-type(3) {
   background-image: url('images/rs-016.jpg');
   animation-delay: 24s;
   }
#x-fade div:nth-of-type(4) {
   background-image: url('images/rs-115.jpg');
   animation-delay: 16s;
   }
#x-fade div:nth-of-type(5) {
   background-image: url('images/rs-080.jpg');
   animation-delay: 8s;
   }
#x-fade div:nth-of-type(6) {
   background-image: url('images/rs-358.jpg');
   animation-delay: 0s;
   }
@-webkit-keyframes xFade { /* from Cross Fade Timings generator */
   /* Images 6, Delay 8s,
   Fade 2.5s, Duration 48s */
   0% {opacity:1}
   11.458% {opacity:1}
   16.667% {opacity:0}
   94.792% {opacity:0}
   100% {opacity:1}
   }
@keyframes xFade { /* from Cross Fade Timings generator */
   /* Images 6, Delay 8s,
   Fade 2.5s, Duration 48s */
   0% {opacity:1}
   11.458% {opacity:1}
   16.667% {opacity:0}
   94.792% {opacity:0}
   100% {opacity:1}
   }
Look carefully at the sequence of numbers in the above styles; where the div:nth-of-type() selector numbering is from the top, but the associated CSS property animation-delay: 0s; starts at the div:nth-of-type(6) selector, and with the prescribed delay of 8s, increases by that amount until it reaches 40s at the div:nth-of-type(1); selector.  The duration of this image sequence is 6 x 8s = 48s, which is declared in the #x-fade div selector as animation-duration: 48s;.

This reverse sequencing of the animation-delay is as a result of the images being loaded sequentially from (1) to (6), where image (6) (or last image) is actually on top of the others, (as the images are stacked vertically and absolutely positioned) and is the first to be faded to reveal the image beneath it, i.e. (5).  This sequence continues as defined in the @keyframes opacity timings until the animation-iteration-count: infinite; causes the sequence to repeat.

There is one CSS property that needs some explanation,graphic i.e. animation-timing: ease-in-out;.  The value "ease-in-out" provides as its name suggests, a non-linear transition using a slow start, a linear middle section followed by a non-linear slow finish.  This is represented in the graphic by time along the X axis (as percentage of the delay selected) and opacity in the Y axis using CSS opacity selector units of 0 to the maximum of 1, where the bottom is opacity: 1; with opacity: 0; at the top.

As described, this CSS is essentially that used in the example Cross Fading Slideshow, and all that's required to get it working elsewhere are 6 images, resized to a common width and height (change the CSS to match) along with the appropriate urls to those background-images.  Providing your images are of a similar aspect ratio, it is possible to resize them by using the background-size property in the #x-fade div selector.

Other options such as the border-radius property can be applied to both the #x-fade and the #x-fade div selectors.  The border-shadow property can also be applied to the #x-fade selector.

Enjoy and experiment with as many images, delay and cross-fade timings as takes your fancy.

NOTE: The final Part 3 of this Cross Fade Slideshow description will deal with how to give meaningful search engine recognized descriptions or titles to each image in the slideshow.  These titles can optionally be visible or invisible without using brute force techniques such as display: none; thus adding recognition to your site's content.

<< Part 1 Part 3 >>

Barry Carlson - 17 December 2014