Use CSS if you can then fall back to JavaScript

September 21st, 2012

I have a rule when I’m making a website and that’s if you can do it with CSS, then do it with CSS. And recently I had a situation where I was updating some slideshows on a site and it gave me to perfect opportunity to follow this rule. The sliders were made with Flash because I’d made them 4 years ago and since I only updated them once a year and the client was fine with how they were, I just ended up throwing in new images. But this year, I had some extra time and I realized, it would be so much quicker and easier to just throw new images into a folder then have to remake the sliders in Flash.

I wanted to use CSS to handle the fading in and out transitions that the slideshow was going to have. But, of course, no version of Internet Explorer supports CSS transitions (IE 10 will, but that’s a while off yet), in order to make it work I would also have a JavaScript backup. Why did I want to use CSS transitions and why didn’t I just do the whole thing in JavaScript? Remember, JS can only do one thing at a time, so if we can offload the transition effect to CSS and that’s one less thing the JS engine needs to worry about. I’m not going to go line by line, I’m just going to go over the basics. But you can check out the full code here.

The first thing we need to do is load modernizr to check if the browser supports opacity or CSS transitions. And our basic CSS looks something like this:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
.slider {
   width: 261px;
   height: 193px;
   overflow: hidden;
   position: relative;
   border: 5px solid #000;
   margin: 30px auto 0;
}
.slider img {
   position: absolute;
   top: 0;
   left: 0;
   opacity: 0;
}
.csstransitions .slider img {
   -webkit-transition: opacity 2s ease-in-out;
   -moz-transition: opacity 2s ease-in-out;
   -ms-transition: opacity 2s ease-in-out;
   -o-transition: opacity 2s ease-in-out;
   transition: opacity 2s ease-in-out;
}
.slider .show {
   opacity: 1;
}

The key here is that we set all the images in our slider to have an opacity of zero and we use the csstransitions class modernizr will add to our html tag so that only browsers that support them will bother with that CSS. And we create a class called show that we’ll apply to the image we want to be visible.

1
2
3
4
5
6
7
8
if ($('html').hasClass('no-opacity')) {
   for (var i = 0; i < imgs.length; i++) {
       $(imgs[i]).css('opacity', '0');
   }
   $(imgs[0]).css('opacity','1');
} else {
   $(imgs[0]).addClass('show');
}

We check if the browser supports opacity, if it doesn’t then we use jQuery to give all the images an opacity of zero, except the first image. If the browser does support opacity, then we just need to apply the show class to the first image.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
function slideShowCSS() {
   if (timer < slideTime) {
       timer += 10;
   } else if (timer >= slideTime) {
       if (curImg < imgs.length - 1) {
           $(imgs[curImg]).removeClass('show');
           curImg += 1;
           $(imgs[curImg]).addClass('show');
       } else {
           $(imgs[curImg]).removeClass('show');
           curImg = 0;
           $(imgs[curImg]).addClass('show');
       }
       timer = 0;
   }
}

This function essentailly does one thing, it increases a variable called timer until it’s more or equal to a variable called slideTime and if it is, it removes the class show from the current image and adds it to the next image. Then the CSS takes care of the fade effect. There’s also a function called slideShowjQuery which is pretty much the same, but instead of removing and adding a class, it uses jQuery’s animate method to get the fading effect. How does the code know which function to call?

1
2
3
4
5
if ($('html').hasClass('csstransitions')) {
   setInterval(slideShowCSS, 20);
} else if ($('html').hasClass('no-csstransitions')) {
   setInterval(slideShowjQuery, 20);
}

The same way we checked if the browser supported opacity or not. We check if the html tag has a class of csstransitions and if it does, then we use setInterval to call slideShowCSS every 20 milliseconds. If it has no-csstransitions, then we call slideShowjQuery.

You can check out the full code on Github. Remember, this isn’t a plug-in that you can configure, it was built to do one thing. But I thought that it was a good example of how we should be coding where we use CSS when we can to free up our JavaScript to do the things it’s best at.

One Response to Use CSS if you can then fall back to JavaScript

  1. betsy says:

    I love this principle, Mike! Your post definitely inspires me to develop by it more frequently. Thanks!

Leave a Reply

Your email address will not be published. Required fields are marked *