Image Slider/Carousel with Fade Effects

image slider/carousel
Almost all educational resources can now be found in the Internet. Thanks to the people who shared their knowledge with everybody. Kudos to all of them. I have to admit that I didn’t knew how to make an image slideshow/carousel by myself, not without the help of W3Schools, using their tutorial here. Thanks to that lesson, I was able to build an image slideshow (aka Image Slider or Image Carousel) of my own. This image slider is complete with a fade effect animation. The slide animations are handled by Javascript, while the graphical end are taken care of by CSS (Cascading stylesheet).

If you wanna see my work, I’ve packed all the components into a zipped file. You can download the file here. I’m sharing it for every one, feel free to modify, but please do mention me when you are using my work.

Trivia

The images I’m using here are from View Master’s Snoopy and the Red Baron Reel. The Reel is a disk that contains photographic films. You can view this films with View Master while facing a light source.

These images make me feel nostalgic.

Copyright Notice

Just a heads up, the images of Snoopy and the Red Baron is a trademark of Peanuts Worldwide LLC. View-Master® is a registered trademark owned by Mattel.

Let’s discuss code

HTML

<html>
<head>
	<title>Slideshow/Carousel</title>
	<meta charset="UTF-8">
	<meta name="viewport" content="width=device-width, initial-scale=1.0" />
	<link rel="stylesheet" type="text/css" href="css/styles.css">
</head>
<body>
<div class="slideshow_box">
	<div class="slides fade">
		<div class="slidenumber">1 / 4</div>
		<img src="images/slideshow_00.jpg" class="full-width">
		<div class="caption">View-Master: Snoopy and the Red Baron Cover</div>
	</div>
	<div class="slides fade">
		<div class="slidenumber">2 / 4</div>
		<img src="images/slideshow_01.jpg" class="full-width">
		<div class="caption">Snoopy and the Red Baron Intro</div>
	</div>
	<div class="slides fade">
		<div class="slidenumber">3 / 4</div>
		<img src="images/slideshow_02.jpg" class="full-width">
		<div class="caption">Snoopy and the Red Baron Part 1</div>
	</div>
	<div class="slides fade">
		<div class="slidenumber">4 / 4</div>
		<img src="images/slideshow_03.jpg" class="full-width">
		<div class="caption">Snoopy and the Red Baron Part 2</div>
	</div>
	<a class="prev" onclick="slide_dir(-1)">&#10094;</a>
	<a class="next" onclick="slide_dir(1)">&#10095;</a>
</div><br>
<div class="dot_container">
	<span class="dots" onclick="presentSlider(1)"></span>
	<span class="dots" onclick="presentSlider(2)"></span>
	<span class="dots" onclick="presentSlider(3)"></span>
	<span class="dots" onclick="presentSlider(4)"></span>
</div>
<script type="text/javascript" src="js/carousel.js"></script>
</body>
</html>

Nothing much to talk here, except maybe for the unicodes at line 30 and 31. They create the ❮ and ❯ arrow keys.

However, for those who doesn’t quite understand what we did here, we created a slideshow container first (class: slideshow_box). Inside these container, we have 4 additional containers for the slides. We are using these containers only for the purpose of making the slides appear and disappear, which we will discuss later in the CSS part.

Inside the slides fade control containers, we have several elements — 2 divisors and one image element. Div slidenumber is for the page/slide number. Img to display the picture, and caption is for the image caption. We can make this caption stay inside or go out of the container. We’ll discuss it later on.

The dots_container at line 33 is for the dots or the slider bullets that we are going to use for easy page navigation.

CSS

body {
	background-color: #aaa;
}

* {
	box-sizing: border-box;
}

.full-width {
	width: 100%;
}

/* Slideshow box */
.slideshow_box {
	max-width: 1024px;
	position: relative;
	margin: auto;
}

/* Hides the images by default */
.slides {
	display: none;
}

/* Fading effect animation */
.fade {
	-webkit-animation-name: fade;
	-webkit-animation-duration: 1.5s;
	animation-name: fade;
	animation-duration: 1.5s;
}

@-webkit-keyframes fade {
	from {
		opacity: .4;
	} to {
		opacity: 1;
	}
}

@keyframes fade {
	from {
		opacity: .4;
	} to {
		opacity: 1;
	}
}

/* Slideshow Number Texts */
.slidenumber {
	color: #f2f2f2;
	font-size: 12px;
	padding: 8px 12px;
	position: absolute;
	top: 0;
	text-shadow: 2px 2px #000;
}

/* Caption Text */
.caption {
	color: #f2f2f2;
	font-size: 15px;
	padding: 8px 12px;
	position: static;
	bottom: 8px;
	width: 100%;
	text-align: center;
	text-shadow: 2px 2px #000;
}

/* Next and Previous buttons */
.prev, .next {
	cursor: pointer;
	position: absolute;
	top: 50%;
	width: auto;
	margin-top: -22px;
	padding: 16px;
	color: #fff;
	font-weight: bold;
	font-size: 18px;
	transition: 0.6s ease;
	border-radius: 0 3px 3px 0;
	user-select: none;
	transform: translate(0%, -50%);
	-webkit-transform: translate(0%, -50%);
}

/* Positions the next button to the right */
.next {
	right: 0;
	border-radius: 3px 0 0 3px;
}

/* On hover, adds a black background color with a little bit see-through effect */
.prev:hover, .next:hover {
	background-color: rgba(0, 0, 0, 0.8);
}

/* The dots/slide bullet */
.dots {
	cursor: pointer;
	height: 15px;
	width: 15px;
	margin: 0 2px;
	background-color: #bbb;
	border-radius: 50%;
	display: inline-block;
	transition: background-color 0.6s ease;
}

.active, .dot:hover {
	background-color: #717171;
}

.dot_container {
	text-align: center;
}

Most of our graphical features are handled by our CSS. Let’s explain it line by line…

Line 1: body style. You can change the background color of the body of the web page here.

Line 5: * (asterisk) is a universal selector. It matches any HTML tag (ie. <div>, <body>, etc.). In this case, we are applying the style box-sizing: border-box to all of the HTML tags in our web page.

What does box-sizing do? By default, in the CSS box model, the width & height we assign to an element is applied only to the element’s content box. If the element has any padding or border, this is then added to the width & height to arrive at the size of the box that’s rendered on the screen. Meaning, when you set width & height, you have to adjust the value you give to allow for any border or padding that may be added.

The box-sizing property “border-box” tells the browser to account for any border & padding in the values specified for an element’s width & height. Using this property, the content box will shrink to absorb any extra width & height.

Line 9: is used by the image to make it responsive. Giving it 100% width allows our images to go large and shrink base on window size.

Line 14: is class for the slideshow_box container. Max-width sets the maximum width our slideshow container (along with its contained elements) can stretch. This is despite given the width 100%, the container will only go as far 1024 pixels, from here it will stop adjusting to the window size.

Giving it position: relative allows it to be positioned relative to its normal position. While margin: auto sets the margins of the box to automatic. Meaning, the margins will adjust on its own.

Line 21: Allows us to hide our image. display: none will remove the image from the container.

Line 26: Creates the fade effect animation. -webkit-animation-name and -webkit-animation-duration is the same as animation-name and animation-duration. The only reason why we included it here is so that it will also allow our fade animation to work in browsers such as Chrome, Safari, and Opera. animation-name is use to call the animation defined under @keyframes animation. animation-duration specifies how long the animation will complete its cycle. Setting it longer will make the transition take longer to complete, while reducing its value make the animation run faster.

Line 33 and 41: This is the animation called by class .fade (lines 27 & 29). opacity creates the fading effect as it makes our image transparent. In our css, our browser is instructed that it should make our picture’s opacity start from being transparent (.4) to solid (1).

Line 50: is the style for our Slide number (ex. 1/4) that appears floating at the top-left column of our slide. I am assuming you guys already understand what color, font-size, and padding mean. So let’s focus only on position: absolute, top, and text-shadow.

The absolute position positions our slide number container to the nearest positioned ancestor. In this case, our main slide_show box since slides doesn’t have a defined position and is therefore default to static. If an absolute positioned element has no positioned ancestors, it uses the document body, and moves along with page scrolling.

The Top property affects the vertical position of a positioned element. This property has no effect on non-positioned elements. We are setting this to 0, which means our box for slide numbers should stick on the top edge of the positioned element.

The property text-shadow gives our texts a shadow effect, in this case, a colored black, drop shadow.

Line 60: is the style for the image caption. In the tutorial provided by W3CSchools, the position of this element is absolute, which makes it position inside the ancestor element. In short, it’s found inside the slide container. In my version of the slider, I position it to static so it would break free from the ancestor element and be pushed out of the container.

The property bottom is the opposite of top. Actually, in our CSS, this is useless because we are out of the box, making our element non-positioned. But, I have included it still in case you guys decide to make the caption box absolute.

Line 72: This is the style for the slideshow arrows. cursor: pointer, makes our mouse cursor turn into a pointing hand. Top 50% should push our arrows halfway of the container, however, there is a slight miscalculation here since we push caption out of the container. The browser still believes that caption is still inside the container so it still includes caption in the height calculation, but since it’s clearly outside, our box shrink and it made our arrows look slightly go further down, beyond half-point. To readjust this, I included transform and -webkit-transform property to counter the 50% top property by translating the y-axis to -50%. For Internet Explorer 9, if there is someone still using it, -ms-transform: translate(0, -50%) should be included in the CSS.

We are also using transition for this to create a similar fading in effect upon hover. For this, we may also need to specify .prev:hover and .next:hover later. CSS transitions allow us to change property values smoothly (from one value to another), in this case, from semi-transparent to solid. The duration we are using is 0.6 second then “ease” which specifies a transition effect with a slow start, then fast, then end slowly.

Property border-radius at line 83, gives the sides of our arrow containers some curves. user-select on line 84, specifies whether the text of an element can be selected. In this case, we set it to none, which subsequently prevents text selection.

Line 90: this positions our next button to the right. The property that makes it happen is right: 0.

Line 96: now this is for our transition. This is the property we want to apply when we hover over the arrow buttons. Technically, this is the initial transition before our buttons turn to solid.

Line 101: This is the style used by dots or our page bullets. Some of these styles have already been explained above so I’ll only focus on display: inline-block. What this does is that it displays our list items horizontally instead of vertically.

Line 112: This is our hover effect. It is also the initial transition effect for the page bullets.

Line 116: Our class for the page bullets container. All it does is contain our bullets so we could align it to the center of the page.

Javascript

var slidePage = 1;
showSlides(slidePage);

// Next/Previous
function slide_dir(n) {
	showSlides(slidePage += n);
}

// Dots
function presentSlider(n) {
	showSlides(slidePage = n);
}

function showSlides(n) {
	var i;
	var slide = document.getElementsByClassName("slides");
	var dot = document.getElementsByClassName("dots");
	if (n > slide.length) {
		slidePage = 1;
	}
	if (n < 1) {
		slidePage = slide.length;
	}
	for (i = 0; i < slide.length; i++) {
		slide[i].style.display = "none";
	}
	for (i = 0; i < dot.length; i++) {
		dot[i].className = dot[i].className.replace(" active", "");
	}
	slide[slidePage - 1].style.display = "block";
	dot[slidePage - 1].className += " active";
}

Now, for our slideshow handler. Note that we inserted this code right after the slideshow_box div. The reason for that is because we are calling .getElementsByClassName. It only works once the CSS is loaded and applied to our divs. If this function is called before the div lines start, our function will return an empty array.

Line 1: set up var slidePage = 1 because we begin on page 1 of the carousel.

Line 2: calls the function showSlides(page number). Note that showSlides is a custom function that we are going to create in the next couple of lines in our code.

Line 5: we are creating a custom function for slide_dir. This is called by our prev/next arrows. The n inside the parenthesis corresponds to the -1 and 1 number in our HTML file. In the next line (6), we are calling the function showSlides wherein if we click on the arrow key, depending on either we press prev or next, it will add slidePage value which is 1 to either -1 or 1.

Line 10: function for the presentSlider use by our dot bullets. n here corresponds to the number 1,2,3, or 4 in our HTML file. Like function slide_dir, this calls for a certain slideshow page.

Line 14: this is our DOM manipulator function. It has the capability to change the class property of our CSS.

Line 15: declare var i. This is an empty variable.

Line 16: var slide makes use of the javascript function to get the class properties inside a class name. For this one, our class name is slides. Therefore, it will retrieve .slides in our CSS file.

Line 17: Similar to line 16 function, but this one retrieves .dots in our CSS file.

Line 18: Creates a condition that if the page number is greater than the page length, which is 4, since it would count all the divs with class name slides and we have 4 of them, then it would set our slider page to 1. This makes sure that our slider don’t go beyond the maximum number of slides.

Line 21: Creates a condition that if our page number is less than 1 then it would set our page to slide.length, which is 4. Of course, if we add more slides then this value will also increase. This makes our slider not go below 1. Should it go below 1, it would move to the 4th slide.

Line 24: This is a for loop. The condition is that if i is less than the slide.length (4), then increment i. This will create slide[0], slide[1], slide[2], slide[3] and set their display value to none (display: none). This loop hides our slides.

Line 27: This is a for loop for the dot bullets. The condition is that if i is less than the dot.length (4), then increment i. This will replace all active dots to nothing, removing the active style for the dot.

Line 30: This changes the style display property of a slide to block. Making it appear.

Line 31: This changes the class name of a dot bullet, setting it to active. Which changes the color of our dot bullet as per our CSS style.

If you guys have questions about the code, feel free to ask on the comments below. The same if you want to suggest something you think could make our code better.

Follow me at:

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.