Fullscreen Background Image Slideshow with CSS3

Happy new year, everybody! Today we will create a CSS-only fullscreen background image slideshow. We'll create different image transitions and also make a title appear using CSS animations.

CSS3FullscreenSlideshow

View demo Download source

Happy new year, everybody! Today we will create a CSS-only fullscreen background image slideshow. We’ll create different image transitions and also make a title appear using CSS animations.

The images are by Mark Sebastian and they are licensed under the Creative Commons Attribution-ShareAlike 2.0 Generic License.

Note that this will only work in browsers supporting CSS animations.

This tutorial is a part of our latest CSS3 experiments; you can find more of those here:

The Markup

We’ll use an unordered list for the slideshow and we’ll add a span for each image and a division with a heading:

<ul class="cb-slideshow">
	<li>
		<span>Image 01</span>
		<div>
			<h3>re·lax·a·tion</h3>
		</div>
	</li>
	<li><!--...--></li>
	<li><!--...--></li>
</ul>

The spans are going to be the elements that will have the background images of the slideshow.

The CSS

Let’s style the unordered list first. It will be fixed and we will stretch it over the viewport. We’ll also use a :after pseudo-element in order to place a pattern on top of the image:

.cb-slideshow,
.cb-slideshow:after { 
    position: fixed;
    width: 100%;
    height: 100%;
    top: 0px;
    left: 0px;
    z-index: 0; 
}
.cb-slideshow:after { 
    content: '';
    background: transparent url(../images/pattern.png) repeat top left; 
}

We’ll use a repeated dot pattern but you could as well use, for example, a css gradient with some transparency.

The span that will contain a slideshow image will be positioned absolutely and have a width and height of 100%. Since we have some text inside, we’ll make the color transparent because we don’t want to see it. The background-size property value “cover” will make sure that the background image covers all the area of the element and hence it is the size of the screen, it will cover all the visible viewport. The opacity is set to 0. We’ll then change that in our animation:

.cb-slideshow li span { 
    width: 100%;
    height: 100%;
    position: absolute;
    top: 0px;
    left: 0px;
    color: transparent;
    background-size: cover;
    background-position: 50% 50%;
    background-repeat: none;
    opacity: 0;
    z-index: 0;
    animation: imageAnimation 36s linear infinite 0s; 
}

The animation for each span will last 36 seconds and run an inifinite number of times. But let’s look at the details in a while, first, we will style the division with the headline:

.cb-slideshow li div { 
    z-index: 1000;
    position: absolute;
    bottom: 30px;
    left: 0px;
    width: 100%;
    text-align: center;
    opacity: 0;
    color: #fff;
    animation: titleAnimation 36s linear infinite 0s; 
}
.cb-slideshow li div h3 { 
    font-family: 'BebasNeueRegular', 'Arial Narrow', Arial, sans-serif;
    font-size: 240px;
    padding: 0;
    line-height: 200px; 
}

The animation for the title division will also take 36 seconds.

Now, we will define the background images for all the spans and the animation delay, so that each following slideshow image and title appear after 6 second of the previous one:

.cb-slideshow li:nth-child(1) span { 
    background-image: url(../images/1.jpg) 
}
.cb-slideshow li:nth-child(2) span { 
    background-image: url(../images/2.jpg);
    animation-delay: 6s; 
}
.cb-slideshow li:nth-child(3) span { 
    background-image: url(../images/3.jpg);
    animation-delay: 12s; 
}
.cb-slideshow li:nth-child(4) span { 
    background-image: url(../images/4.jpg);
    animation-delay: 18s; 
}
.cb-slideshow li:nth-child(5) span { 
    background-image: url(../images/5.jpg);
    animation-delay: 24s; 
}
.cb-slideshow li:nth-child(6) span { 
    background-image: url(../images/6.jpg);
    animation-delay: 30s; 
}

.cb-slideshow li:nth-child(2) div { 
    animation-delay: 6s; 
}
.cb-slideshow li:nth-child(3) div { 
    animation-delay: 12s; 
}
.cb-slideshow li:nth-child(4) div { 
    animation-delay: 18s; 
}
.cb-slideshow li:nth-child(5) div { 
    animation-delay: 24s; 
}
.cb-slideshow li:nth-child(6) div { 
    animation-delay: 30s; 
}

Now, let’s have a look at the slideshow animation. Each span will have an animation time of 36 seconds. In those 36 seconds we will change the opacity from 0 to 1 when the animation reaches 8%. And then this opacity gets kept until 17% are reached. When reaching 25% the opacity should already be 0 again and stay like that until the end.

Now, why those values? We want each image to be visible for 6 seconds and we know that at the end of a cycle, we want the first image to show again. We have 6 images, so we will need 36 seconds for a whole cycle to finish. Now, we need to “time” the opacity values accordingly. Knowing that our second image will start animating at 6 seconds, we need to know at what percentile of the animation this will require the first image to fade out. Dividing 6 by 36 gives us 0.166… which would be 16% for our keyframe step. Now, because we don’t want our image to just fade all the time, we’ll define an inbetween step, which we’ll set at half of what we calculated, i.e. 8%. That’s the point that we want to show the image completely and we only want to start fading it out at 17%, making it disappear completely at 25%.

@keyframes imageAnimation { 
    0% { opacity: 0; animation-timing-function: ease-in; }
    8% { opacity: 1; animation-timing-function: ease-out; }
    17% { opacity: 1 }
    25% { opacity: 0 }
    100% { opacity: 0 }
}

We have the same reasoning for the title, just that we want it to disappear a bit quicker, hence the opacity 0 at 19%:

@keyframes titleAnimation { 
    0% { opacity: 0 }
    8% { opacity: 1 }
    17% { opacity: 1 }
    19% { opacity: 0 }
    100% { opacity: 0 }
}

For browsers that don’t support animations, we’ll simply show the last slideshow image by setting the opacity of the span to 1:

.no-cssanimations .cb-slideshow li span{
	opacity: 1;
}

The no-cssanimations class is added by Modernizr.

Let’s as well take care of the title’s font size when the viewport is smaller. We’ll use media queries in order to set the font size smaller at specific widths:

@media screen and (max-width: 1140px) { 
    .cb-slideshow li div h3 { font-size: 140px }
}
@media screen and (max-width: 600px) { 
    .cb-slideshow li div h3 { font-size: 80px }
}

And that’s all for the simple version of the slideshow! Now, let’s see how we can spice up the transitions a bit.

Alternative animation example

Now, we can play a bit with the animations for showing the images and their titles.

The following animation will make the image scale up a bit and rotate it slightly:

@keyframes imageAnimation { 
	0% {
	    opacity: 0;
	    animation-timing-function: ease-in;
	}
	8% {
	    opacity: 1;
	    transform: scale(1.05);
	    animation-timing-function: ease-out;
	}
	17% {
	    opacity: 1;
	    transform: scale(1.1) rotate(3deg);
	}
	25% {
	    opacity: 0;
	    transform: scale(1.1) rotate(3deg);
	}
	100% { opacity: 0 }
}

The title will slide in from the right (we’ll have to change the text-align for the title division to “right”), and disappear by sliding to the left and fading out:

@keyframes titleAnimation { 
	0% {
	    opacity: 0;
	    transform: translateX(200px);
	}
	8% {
	    opacity: 1;
	    transform: translateX(0px);
	}
	17% {
	    opacity: 1;
	    transform: translateX(0px);
	}
	19% {
	    opacity: 0;
	    transform: translateX(-400px);
	}
	25% { opacity: 0 }
	100% { opacity: 0 }
}

There are many possibilities for the image and title transitions, just experiment!

Demos

Here you can find some demos with alternative animations:

  1. Demo 1: Simple Fade in, fade out
  2. Demo 2: Slight rotation, title slides from the right
  3. Demo 3: Image moves up, title moves down
  4. Demo 4: Image scales, title moves up, scales and fades out

Currently, the animations are smoothest in Webkit broswers like Chrome and especially Safari.

I hope you enjoyed this tutorial and find it useful and inspiring!

View demo Download source

Previous:
Next:

Tagged with:

Mary Lou (Manoela Ilic) is a freelance web designer and developer with a passion for interaction design. She studied Cognitive Science and Computational Logic and has a weakness for the smell of freshly ground peppercorns.

View all contributions by

Website: http://tympanus.net/

Related Articles

Feedback 147

Comments are closed.
  1. 1

    Hello,

    I really like your tutorial.
    There only seems to be a problem when zooming in or making multitouch gestures on the iPad.
    I don’t know how to solve this.
    Even when disabling the zoom option by setting meta tag:

    It still crashes when the multi touch gestures are done..

    Can anyone help me?

    Regards!

    • 3

      That’s why Internet explorer doesn’t support any kind of css3 transitions or effects, for example: animation-timing-function, animation, animation-delay and more, It’s really simple, If you want to see or use CSS3 effects like transitions, transform and more, then you SHOULD Dump Internet Explorer.

      Btw Mary! this tutorial it’s really awesome and usefull! I was wondering how to do something like that just with CSS3! thanks for sharing!

  2. 4

    Hi great work!! I’m wondering how I can combine this with lets say the slideshow with parallax effect on top. Not with regards to multiple java-script but where in the div structure, believe me Ive tried. Thank you.

  3. 5

    Hello,
    Thanks for this tutorial. GREAT WORK !
    I want to use it with a video background
    Do you know how to do it ?

  4. 6

    this is great, but, is there a way to make the images show in randome order?

  5. 8

    I get an odd effect when I attempt to cut down the slides to 3, the first slide fires fine, but the second one just goes to black, then 6 seconds later it displays the actual second image, does the same thing for the 3rd(goes to black) then displays the actual 3rd slide.

    Any ideas on how to fix this?

  6. 10

    Love it other then it lags the crap out of my site. Can you make a pause please thanks.

  7. 11

    Just managed to implement it in this background slideshow in Drupal… to save others some other some time here are the steps:

    – paste the markup into page.tpl.php of your template, right at the top just under the first tag
    – paste the css into styles.css of your template, at the bottom
    – in the css change all the z-index values to -1
    -copy the images folder into your template’s root folder
    – copy the fonts folder into the template’s css folder

    that should be it…

  8. 12

    The demo seems to break in Chrome (19.0.1084.46) if you switch to a different tab and return. In the page I’m building based on this method, removing “-webkit-backface-visibility: hidden;” from the CSS seemed to resolve the issue.

  9. 13

    OK: so “-webkit-backface-visibility: hidden” tells webkit to treat the images as a 3D object which triggers it to perform the animation using webGL, which is _mostly_ a good thing, because it makes the animation WAAAAY smoother in Safari.

    The downside of that line of CSS is that up to somewhere around Chrome 21.X canary (unreleased as of yet) triggering webGL causes the CSS Animation’s to all reset if you switch tabs and return to the page. This not only resets the gallery to play from the beginning, it removes the animation-delays causing all the animations to play at the same time resulting in a completely broken gallery.

    To fix this on my website, I moved the “-webkit-backface-visibility: hidden” into a selector .use-web-gl { }, then on my page, I add this class to all browsers except versions of Chrome before ‘canary’ using jQuery as follows:


    if ( $.browser.webkit && !!window.chrome && $.browser.version < 537.1 ) {
    // do not use web GL
    } else {
    $(".cb-slideshow li").addClass('use-web-gl');
    }

    By doing this, you get the best of both – webGL in Safari = nice smooth transitions. No web-GL for Chrome < 21.X = no messed up timings when returning from another tab.

    :)

    • 14

      so.. i´m trying to fix mine too.. but i dont understend what u have done with the “-webkit-backface-visibility: hidden”, did u put it on the css class: .use-web-gl { }?

      and this if/else… u put in your page scripts?

      can u show me your exemple of code?
      sry about the nb questions… trying to learn in here T_T…

    • 15

      Could you please show an example? I’m having that issue as well. Thanks!

    • 16

      For anyone who is looking for a snippet of this example:
      /* CSS */
      .use-web-gl {
      -webkit-backface-visibility: hidden;
      }
      /* HTML */
      [page content]

      $(document).ready(function() {
      if($.browser.webkit && !!window.chrome && $.browser.version < 537.1) {
      // do not use web GL
      } else {
      /*
      * Forces fullscreen CSS3 slideshow to use WebGL if browser is able to,
      * because it creates smoother transitions
      */
      $(".slideshow li").addClass('use-web-gl');
      }
      });

      [footer/end body tag area]

      Ideally all you want to do is initialize that chunk of code so that it checks the browser and injects the CSS using jQuery when the browser isn’t that particular Chrome Canary version. Correct me if I’m wrong please, I’m still learning too!

  10. 18

    It doesn’t do anything in Internet Explorer 9 except show just one image. How do you get it to rotate in Internet Explorer 9?

    • 19

      I created a conditional IE statement and created a separate slideshow with a “-ie” class and used the bgStretcher jQuery plugin to drive the same images. It creates a slideshow that looks exactly like the CSS3 one! It’s awesome.

  11. 20

    This is a beautiful script, love smoothness of the simple fading transitions. I have one problem that I wondered if someone might be able help with – the background slideshow does not work in Firefox on OSX. It works fine in Firefox on PC however. Any clues as to why this might be? Many thanks.

  12. 21

    that’s not use js any thing?, thats so beatiful, i’m bookmark so,,, ^^

  13. 22

    Very, very nice, liking this a lot!

    Is there anyway to add the pattern onto the images, yet still below the headlines, any other way than using pseudo-element :after? The reason I am asking is that I can’t use jquery to manipulate the background value.

  14. 23

    it’s very cool. i love this tutorial.
    Anyway it’s has a little problem that i need your solution.
    when start Slide in browser it’s perfectly slides and perfectly loop but when i switch to another tab(same browser) for see something and back to Slide it will be messy slide. I already test with your original Demo it’s show the same results.

    Do you have any solution for this. Thanks you very much.^^

  15. 26

    Hi, I just want to know how did you adjust the image for all type and size of screen ?
    Thanks,
    Louis

Comments are closed.