Tutorials Web Development

Multi-Image Hover Display Rotator with CSS3 & jQuery

4.67/5 (3)

Most image rotators are created with sliding arrows or dot navigation. But what if we could build an image gallery that contains that navigation within itself? In this tutorial I want to explain you how to make image hover css3 based gallery.

The container itself has invisible columns which take up the entirety of the carousel. As the user hovers onto the carousel the primary image will switch based on which column is highlighted. Each of the columns are also hyperlinks which lead out to the full image view. To see this effect in action take a peek at my live sample demo below:

Live Demo Download Source Code

Getting Started

The first step is to create a blank HTML5 page with a separate directory for the stylesheet and jQuery library. I'm using a separate file named styles.css to hold the page CSS.

1
2
3
4
5
6
7
8
<!doctype html>
 
  Multi-Image Display Widget - Template Monster Demo
 
 
 
 
  <script type="text/javascript" src="js/jquery-1.11.1.min.js"></script>

The page itself contains a wrapper holding all the content. Inside the wrapper is another div containing the image rotator using the class .fullsize-rotator. With a single class name we can initiate multiple image rotators on the same page.

Inside the rotator are two distinct sections: one section holds the image and the top navbar while the other sections holds the navigation links. Since the entire image carousel is hoverable, the links need to be on top of everything else. Picture it like a series of transparent columns that span the entire height of a container. Each column will be selected when hovered and change the background image on hover.

 

 

 

 

 

 

 

 

Also notice that each HREF value leads to a different image. This means visitors are able to click any of the column links and be directed to a fullview of that image.

Within the div .imgcontent we have a section full of different span elements. These elements create the small rectangular blocks which appear at the very top of the image rotator. Each rectangle represents a link and turns dark when selected. This way users can navigate the columns a whole lot easier.

CSS Page Styles

Aside from my typical page resets the structure is fairly basic. Inside the wrapper we have a div with the class .fullsize-rotator. I'm using a fixed width because the background image renders as an absolute element. This means the image is removed from the document flow and we don't have a way to obtain the image's width or height. So to compensate I'm using fixed values on the container.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
/** image rotator carousel **/
.fullsize-rotator {
  display: block;
  position: relative;
  width: 750px;
  height: 450px;
  margin: 0 auto;
  margin-bottom: 25px;
  background: #fff;
  -webkit-box-shadow: 0 0 5px rgba(0,0,0,0.25);
  -moz-box-shadow: 0 0 5px rgba(0,0,0,0.25);
  box-shadow: 0 0 5px rgba(0,0,0,0.25);
}
 
.fullsize-rotator .imgcontent {
  position: absolute;
  top: 0;
  width: 100%;
  height: 100%;
  overflow: hidden;
  padding: 5px;
}

Using a relative position for the image container we can use absolute positioning for .imgcontent. This will force the image itself along with the rectangles to appear right at the top of the rotator. I'm also using the z-index property to force the navigation links on top of the image. Users will be able to see all of the content but they can only interact with the links.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
.rotator-nav {
  display: block;
  position: relative;
  width: 100%;
  height: 100%;
  z-index: 9;
}
.rotator-nav li {
  display: block;
  float: left;
  height: 100%;
}
 
.rotator-nav.fourth li {
  width: 25%;
}
.rotator-nav.fifth li {
  width: 20%;
}
 
.rotator-nav li a {
  display: block;
  float: left;
  width: 100%;
  height: 100%;
}
 
.rotator-icons {
  display: block;
  position: absolute;
  width: 740px; /** fixed based on padding */
  height: 0px; 
}
.rotator-icons span {
  display: block;
  float: left;
  height: 100%;
  background: rgba(255,255,255,0.7);
}
.rotator-icons span.active {
  background: rgba(55,55,55,0.7);
}
 
.rotator-icons.fourth span {
  width: 25%;
}
.rotator-icons.fifth span {
  width: 20%;
}

The class .rotator-nav refers to an unordered list of links which control the entire interface. These are visible at all times and hold the URLs to each individual image. Notice the additional classes of .fourth and .fifth which can be attached to the list container. These represent how large the columns should be - 20% for five items(one-fifth), 25% for four items(one-fourth).

Using some math you can make other classes for any various number of list items. Beyond a certain point the links will probably be too small, but it's always possible to enlarge the image rotator as well.

Now the secondary class .rotator-icons pertains to the span elements. These are the tiny rectangles which appear at the top when hovering. By default they have no height, but animate into view using jQuery. The background property uses an rgba() color value to utilize the alpha channel for slight transparency.

Animating with jQuery

Moving into jQuery there's only two primary goals that need to be accomplished. First we need to display the rectangle navigation whenever a user hovers onto the image rotator. Then we need to update each image & selected rectangle based on which link is currently hovered. This can be accomplished using the mouseenter/mouseleave event handlers.

1
2
3
4
5
6
7
8
var $rotators = $('.fullsize-rotator');
var $imglinks = $('.rotator-nav a');
 
$rotators.on('mouseenter', function(e){
  $(this).find('.rotator-icons').animate({height: '20px'}, 200);
}).on('mouseleave', function(e){
  $(this).find('.rotator-icons').animate({height: '0px'}, 150);
});

My first two lines of code are setting up variables to speed up the selection process. First I'm targeting the rotator and second I'm targeting each of the anchor link columns. Since the rotator uses a class, I chose to name the variable $rotators to include any other possible rotators on the page.

When the user enters a rotator jQuery will find the .rotator-icons container and then animate the height to 20px. This causes the rectangle navigation to seemingly appear from nowhere. Then once the user's mouse leaves the rotator we hide the rectangles again. Simple!

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
$imglinks.on('mouseenter', function(e){
  var imgclass = '.'+$(this).attr('class');
  var imglink  = $(this).attr('href');
 
  // update main image src
  $(this).parent().parent().parent().find('.currentimg').attr('src',imglink);
 
  // update current rotator icon
  var $rotators = $(this).parent().parent().parent().find('.rotator-icons');
 
  if($rotators.children(imgclass).hasClass('active')) {
    // already active icon -- do nothing
  } else {
    // remove active class then add to new icon
    $rotators.children('span').removeClass('active');
    $rotators.children(imgclass).addClass('active');
  }
});

This larger block of code might seem more confusing but it's all very logical. The mouseenter event will fire whenever a user hovers onto one of the anchor links. I'm pulling a variable named imgclass telling us which rectangle needs to be selected. I'm also pulling another variable imglink which contains the new image's hyperlink.

By targeting the nearest image with a class of .currentimg I can update the image source using .attr(). The rectangle icon is also updated, but we first check if the current rectangle is already selected. So if the user hovers onto a link which is already selected then we don't do anything. This is determined using imgclass to see if the related span element also has the .active class. If so then we do nothing because the user is hovering an image that's already visible.

If not then we know the user is hovering onto a new image. First we remove the .active class from whatever rectangle was previously displayed, then append it onto the new rectangle.

We don't need a mouseleave event because when the user leaves the rotator we don't do anything. So the image & selected rectangle icon only get updated when the user hovers onto a new link column.

Final Thoughts

I hope this tutorial can be useful for developers who wish to display multiple images on a page. While it's certainly unique, this may not be the best choice for every website. Keep in mind that touch-based screens like smartphones and tablets won't be able to easily interact with this type of image gallery. But for modern web browsers this can be a great solution which is easy to setup and easy to customize. Feel free to download a copy of my source code and see what else you can build using this template.