View Sidebar

A Million Little Pieces Of My Mind

How to Create A Slide Show in CSS

By: Paul S. Cilwa Viewed: 2/23/2024
Posted: 3/27/2023
Page Views: 336
There are a lot of hints on the Web how to create CSS-only slide shows. This one works.

I recently posted a blog entry inspired by our addition of a new doggie door. I had taken three pictures of my grandson, Dominic, demonstrating the doggie door to the dogs, who understandably were taken aback by it. To display the three photos, I wanted to fade one over the other, as opposed to simply displaying one below the other. However, to my surprise, I found that the instructions to do what I would call a pretty basic function, were murky at best, or very specifically aimed at special circumstances: two or four pictures but not three; or photos of a specific and unchangeable size (not the size of mine). Modifications didn't seem to work; so the only remaining option was figuring it out on my own. But I did, so now you won't have to.

To be clear on what we're working with, here are thumbnails of the three images:

I took all three photos from the same position, and used my preferred software (Zoner Photo Pro to align the three as closely as possible with a handheld phone camera.

When I was looking up how to do the mini-Carousel I wanted, I encountered references to both CSS Transitions and Animations. Both are used to create animations and dynamic effects on web pages, but they work in different ways.

CSS Transitions allow us to create a transition between two states of an element. For example, we can use a transition to smoothly change the background color of a button when the user hovers over it. Transitions are triggered by a change in the state of an element, such as a hover, click, or focus.

CSS Animations, on the other hand, allow us to create more complex animations with more control over the timing and sequence of events. Animations are not triggered by a change in the state of an element, but instead can be set to run automatically or on a loop. In addition, we can use animations to create more complex effects such as a slide show or an animated loading spinner.

When creating a slide show with multiple images that repeat on an infinite loop, CSS Animations would be a better choice than Transitions. With Animations, we have greater control over the timing and sequence of events, allowing us to create more complex and dynamic effects. Additionally, Animations can be set to run automatically, without requiring user interaction.

Using the animation-iteration-count: infinite property, we can set our slide show to run on a loop indefinitely, and can control the duration, delay, and timing function of each animation to create a seamless and visually appealing effect. Being able to repeat the effect indefinitely, alone, makes CSS Animations the better choice in this case over Transitions.

Using CSS to create a Carousel that fades or dissolves from one photo to another is a great way to showcase a series of images in a visually engaging way. The terms "fade" and "dissolve" were originally used in movies to describe the transition from one scene to another. In movies, a fade occurs when the screen gradually becomes black or white, and a dissolve occurs when one image gradually replaces another. Nowadays, these terms are often used interchangeably in online graphics and refer to a smooth transition from one image to another.

We can do this all within CSS (no need to resort to Javascript), and the HTML is simple and intuitive. You should be able to remember the class name and syntax without having to look it up every time.

To start, create a <div> element with the class name "Carousel" and place each photo inside an <img> tag, like so:

<div class="Carousel"> <img src="20230130_152036.jpg" ⁄> <img src="20230130_152038.jpg" ⁄> <img src="20230130_152041.jpg" ⁄> <⁄div>

Until we define a Carousel style for <div> tags, the above code will display the three photos inline, one after the other. In order to place the photos on top of each other instead, we must start by making this <div> relative rather than the default of static. That's because we want the contained photos to all appear in the same space, which we'll do by giving the images an absolute position. If the containing division was static, the left and right properties would position the image relative to the page as a whole, instead of within that division.

When you set an element to position: absolute, it is positioned relative to the nearest positioned ancestor element. If there is no positioned ancestor element, it is positioned relative to the initial containing block (usually the <html> element).

So, if the parent <div> element is position: static, the child <div> element with position: absolute will be positioned relative to the initial containing block. However, if you set the parent <div> element to position: relative, the child <div> element will be positioned relative to the parent element.

So, in our CSS, that's the first definition we provide:

div.Carousel { position: relative; }

I saw some examples online of having two nested <div>s, but that's unneccesary because CSS selection rules let us specify any images contained within the Carousel <div>.

Next, we have this CSS code which selects all img elements that are descendants of a div element with the class "Carousel". The position property is set to absolute, which means that the images will be positioned relative to their closest positioned ancestor, which in this case is the div element with the class "Carousel".

div.Carousel img { position: absolute; top: 0; left: 0; opacity: 0; box-shadow: none; animation-name: Carousel; animation-timing-function: ease-in-out; animation-iteration-count: infinite; animation-duration: 4s; }

There's a significant technique shown here. Some other examples I saw required each image to have its own class name! But CSS allows us to specify "any image inside a <div> of the "Carousel" class.

The top and left properties are set to 0, which means that the images will be positioned in the top left corner of the div.

The opacity property is set to 0, which means that the images are completely transparent and will not be visible until the animation is triggered. This is the behavior we want from all the images except the first, which is something we'll address in a moment.

Now, on this, my personal web site, as of 2023, images are, by default, given a shadow to make them sort of jump out off of the page. If I position other images on top of the first one, the shadows, which are semi-transparent, add up and wind up looking too dark. So, I have to turn off shadows for images in this container; I'll turn it on for the first image shortly.

The animation-name property connects this object to a CSS keyframes function. We'll come back to this shortly.

The animation-timing-function property is set to ease-in-out, which specifies the speed curve of the animation. The ease-in-out value means that the animation will start slow, accelerate in the middle, and slow down again at the end. I find the fades look a little more natural this way.

The a nimation-iteration-count property is set to infinite, which means that the animation will repeat indefinitely.

The animation-duration property is set to 4s, which means that the entire animation will last for 4 seconds.

Let's talk about that four seconds for a moment. In this example, we have three pictures. I want to fade each into the other for a full second, with the final image showing for a full second before fading back to the first image. That means that the first image must always be opaque (visible) since the other images will be displayed "on top of" it. In the code above, all images are set to invisible (opacity: 0).

But we can also reference images within that division by their ordinal position. For example, we have to make the first image always visible; and I also want to replace the standard box-shadow values that we nullified in the vanilla Carousel image style block.

div.Carousel img:nth-of-type(1) { position: relative; opacity: 1; box-shadow: 5px 5px 10px black; animation-name: none; }

We also have to overridde the position property. The reason for this isn't obvious. But the enclosing <div> will not take up any space unless it contains at least one relative or static object; and it sizes itself for exactly that much room.

Finally, we override the vanilla div.Carousel img properties by specifying that this image, the first within the <div>, will not participate in any animation. Instead, it's just gonna sit there while the other images appear on top of it. When they have faded away, this first image will remain.

div.Carousel img:nth-of-type(2) { animation-delay: 1s; } div.Carousel img:nth-of-type(3) { animation-delay: 2s; }

The remaining images, then, merely need to have the animation-delay property adjusted. The first image is already there; the second will start to fade in after the first second; the third will start at the second second.

To do the rapid image switching I want, the animation-duration will always be 1 greater than the number of images. If you have more than three images, just repeat the above :nth-of-type snippets for as many as you like. (Note that there's no practical downside in creating extras for as many images as you can imaging wanting to appear in this manner.

Our last step, the, is defining the animation-name keyframes rule:

@keyframes Carousel { 0% { opacity: 0; } 25% { opacity: 1; } 50% { opacity: 1; } 90% { opacity: 0; } 100% { opacity: 0; } }

This CSS code defines a @keyframes rule with the name Carousel. This rule contains a series of keyframe selectors, each specifying whatever styles that should be applied at a certain point during the animation. Don't be fooled into thinking the @keyframes rule only applies to transparency. You can do movements or practically anything else you can think of.

The first keyframe selector 0% sets the initial state of the element with opacity: 0, which means it will be completely transparent.

The second keyframe selector 25% sets the opacity to 1, which means the element will gradually become totally visible from 0% to 25% of the animation duration.

The third keyframe selector 50% keeps the opacity at 1 for the middle portion of the animation, from 25% to 50% of the animation duration.

The fourth keyframe selector 90% sets the opacity back to 0 towards the end of the animation, at 90% of the animation duration. This means the element will gradually become transparent again, so that it will disappear completely by the end of the animation, revealing at the point the always-visible-when-not-hidden underlying first image.

The fifth keyframe selector 100% also sets the opacity to 0, but it is redundant since it repeats the style from the fourth selector. It is included for clarity and completeness.

Together, these keyframe selectors define the steps of an animation that will cause an element to gradually fade in and out over the course of the animation duration.

The order of what actually happens is this:

The page loads, and image 1 appears. One second later, image 2 begins to fade in on top of image 1. A second after that, image 3 begins to fade in on top of image 2.

But then, while image 3 remains visible, image 2 fades back to invisibility beneath it. So, when image 3 fades a second later, it reveals the first image that was beneath them all. So if you want to change the length of time between images being displayed, do that by altering the animation-delay value for the appearing images, and the animation-duration property accordingly.

In conclusion, creating a Carousel with CSS animations is an effective way to display a series of images on a web page. With CSS Animations, you have greater control over the timing and sequence of events, allowing you to create more dynamic and visually appealing effects. By using the animation-iteration-count: infinite property value, you can set your slide show to run on a loop indefinitely, without requiring user interaction. Remember that when positioning images, it is important to set the parent element to position: relative, so that the child elements are positioned relative to it.

With these tips in mind, you can easily create a beautiful and engaging Carousel.