CSS Only Responsive Carousel

  • follow us in feedly
Published September 27, 2013 by Brad Knutson
CSS Only Carousel

If you’ve read any number of my posts, you are well aware that I’m a huge proponent of CSS over Javascript whenever possible. With recent innovations to CSS3 over the last handful of years, animations that once required Javascript can be accomplished with CSS. This means elements such as hover states, animated navigation bars, showing and hiding items, tabs, accordions, and more can be accomplished without any Javascript.

Today I would like to show you how to create a CSS only image carousel.


Browser Support

All the major modern browsers support this animation. If you’re worried about IE9 or older, you will unfortunately need to use Javascript, as this method is only supported in IE10.

Pretty cool, eh? So how do we go about creating this effect?

The HTML Structure

<div class="css-carousel">
	<img class="css-img" src="path/to/image/1" />
	<img class="css-img" src="path/to/image/2" />
	<img class="css-img" src="path/to/image/3" />
	<img class="css-img" src="path/to/image/4" />
	<img class="css-img" src="path/to/image/5" />
	<img class="css-img" src="path/to/image/6" />


.css-carousel {
	width: 100%;
	height: 350px; /* Height of images */
	position: relative;
	overflow: hidden;
.css-carousel .css-img {
	max-width: 100%;
	position: absolute;
	left: 0;
	right: 0;
	opacity: 0;
	-webkit-animation: css-carousel-fade 30s linear infinite;
	-moz-animation: css-carousel-fade 30s linear infinite;
	-ms-animation: css-carousel-fade 30s linear infinite;
	animation: css-carousel-fade 30s linear infinite;
.css-carousel .css-img:nth-child(2) {
	-webkit-animation-delay: 5s;
	-moz-animation-delay: 5s;
	-ms-animation-delay: 5s;
	animation-delay: 5s;
.css-carousel .css-img:nth-child(3) {
	-webkit-animation-delay: 10s;
	-moz-animation-delay: 10s;
	-ms-animation-delay: 10s;
	animation-delay: 10s;
.css-carousel .css-img:nth-child(4) {
	-webkit-animation-delay: 15s;
	-moz-animation-delay: 15s;
	-ms-animation-delay: 15s;
	animation-delay: 15s;
.css-carousel .css-img:nth-child(5) {
	-webkit-animation-delay: 20s;
	-moz-animation-delay: 20s;
	-ms-animation-delay: 20s;
	animation-delay: 20s;
.css-carousel .css-img:nth-child(6) {
	-webkit-animation-delay: 25s;
	-moz-animation-delay: 25s;
	-ms-animation-delay: 25s;
	animation-delay: 25s;
@-webkit-keyframes css-carousel-fade {
    0%, 20%, 100% { opacity: 0; }
    5%, 15% { opacity: 1;}
@-moz-keyframes css-carousel-fade {
    0%, 20%, 100% { opacity: 0; }
    5%, 15% { opacity: 1;}
@-ms-keyframes css-carousel-fade {
    0%, 20%, 100% { opacity: 0; }
    5%, 15% { opacity: 1;}
@keyframes css-carousel-fade {
	0%, 20%, 100% { opacity: 0; }
	5%, 15% { opacity: 1;}

The above CSS is specifically for 6 images, but it can be modified for any number of image elements with a little bit of math.

One full cycle of the carousel is 30 seconds long, so we break up animation into 5 second sections. Each image is by default set to an opacity of 0 for 5 seconds, and the other 25 seconds the opacity is 1, allowing for the image to be see. We absolutely position the images in the same place, and use some CSS transitions to make the transition smooth and appealing. We then delay each subsequent image by 5 seconds so the animations overlap nicely, creating the carousel effect.

If your carousel is more or less images, you will need to modify the length of the animation, as well as the keyframe selectors. A little bit of math should do the trick.

Let me know if you have any questions by leaving a comment below!

The following two tabs change content below.
Founder at Inbounderish
Brad Knutson is a Web Developer in the Twin Cities area of Minnesota. He has experience working with WordPress and Drupal, and also has an interest in SEO and Inbound Marketing.

Keep Up-to-Date



See a complete list of topics discussed in blog posts here.

Check These Out

Get 2 Weeks Free! Sign Up Today! Premium Managed WordPress Hosting Genesis Framework for WordPress SEO is complex. Tools should be simple. Thesis Theme for WordPress:  Options Galore and a Helpful Support Community

25 thoughts on “CSS Only Responsive Carousel

    1. Brad Knutson Post author

      If you want to link the images in the slider, I suggest you try a regular Javascript or jQuery slider instead, as they’ll give you the flexibility to do that!

    1. Brad Knutson Post author


      It depends on a few things. If you are building the site with a server-side scripting language (like PHP), you could have the server randomly show an image. If you are building the site with just HTML and CSS, and don’t want to use Javascript, unfortunately, you are out of luck.

  1. Steven

    How would you do this form two images? Obviously taking out all of the nth-children except for (2), but how would you make the transitions go smooth with just two images?

    1. Brad Knutson Post author

      Hey Steven, if you saw my previous comment, ignore it. So you want a two image carousel that fades from one to the other in a loop, correct? Or am I missing something? Perhaps the carousel solution is too complicated for this situation – you could create two keyframes, run them on the same interval, and have one fade the first image in and the other fade the second image out.

    2. Steven

      What about the css-carousel-fade?

      Right now I have them all to be:

      0%, 50%, 100% { opacity: 0; }
      5%, 45% { opacity: 1;}

      But there is too much time in between images. To much white being shown.

    3. Steven

      I’m find with the solution you have on your post. My only issue is that the changing of images takes a little too long. There is too much time spend in white space.

  2. Larry

    Any way to do a carousel with just background colors and text, no images? Or would that just be some kind of transformation. New to all this and haven’t found anything like that yet for my dads site.

    1. Brad Knutson Post author


      You could accomplish this with the same idea, but just a little different structure. Replace the image tags with divs, then style those divs however you’d like. Create a keyframe that will fade in and fade out the “slide” and then delay each subsequent slide. Basically the same thing we have here, except with divs instead of image tags.

      Good luck!

  3. Larry

    Thanks Brad,
    I understand what you mean I will look at it after the holiday. Thanks for pointing me in the right direction.

    1. Brad Knutson Post author

      That type of interaction would require Javascript or jQuery, this example is a purely CSS image carousel. Do a Google search for bxslider, and you should find what you’re looking for.

  4. Thatguy2011

    I’m not sure if he was asking this same question, Is it possible to change the background images by pressing the up or down arrow key on your keyboard ?

    1. Brad Knutson Post author

      That would also require Javascript or jQuery, and bxslider supports key controls also.

  5. Oren

    Nice one!

    I wonder if you maybe can add in indicator to show the current slide & maybe allow moving manually through the slides. I’ve seen it with other CSS carousels, but I prefer your fade-in/out affect.

    1. Brad Knutson Post author

      Hello Oren – this type of functionality would be best suited for Javascript or jQuery carousels. I would only suggest using the CSS-only solution for very simple carousels.

  6. Chrno

    Hello Brad.

    Have a questions.
    1. Is it possible to do it with multiple images, when count of images is not defined at start (dynamically added for page)?
    2. Can I add you sample to my GitHub repo and link at readme to you post?

    1. Brad Knutson Post author

      Hey – sure you can add to your repo. As for a dynamically generated carousel, you would also have to dynamically create the CSS (with a server side script or Javascript) because it has to be specific for the number of images in the carousel. Good luck!

  7. Sarah

    Can you elaborate on the “little bit of math” needed to figure out the formula for n pictures? I’m specifically not understanding how to derive the keyframe percentages.

    1. BlackMagic

      Sarah, each image is timed to last 5 seconds. There are 6 images (6 * 5 = 30). If you had 8 images you would need to change the ‘animation:’ to css-carousel-fade 40s linear infinite; and add in two more nth-child(x) clauses, one saying animation-delay: 30s; and one saying animation-delay: 35s;. And two more inages in the sequences.

      I had 4 images I wanted to display. Rather than fiddling with the code I repeated the 3rd image at position 4 and the 2nd image at position 5.

  8. Newman

    I keep running into the same issue, even without any edits to the code, where the second image (nth-child(2)) isn’t being delayed. I’ve tried extending the delay to test, etc., but what happens is the first and second image are loading together, so that during the transitional phase of opacity adjustment you can see them overlapping.

    Something of a CSS noob, obviously. Thanks for any help!


Share Your Thoughts

Your email address will not be shown.

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code class="" title="" data-url=""> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong> <pre class="" title="" data-url=""> <span class="" title="" data-url="">