Expand multiple images on hover with HTML, CSS & JS

Group together a collection of images and get them to expand in all directions on hover


Group together a collection of images and get them to expand in all directions on hover



SA, an Australian agency based in Brisbane, were charged with the task of bringing thousands of state-owned photographs and memorabilia from World War I and presenting them in a meaningful and memorable format for the 21st century. What they came up with was the website A State of War.

This website serves as an archive to bring to life stories from World War I, and the design reflects the idea that this has been preserved in a digital scrapbook. The design obviously contains many sepia-toned images and so these colours provide the warm backdrop for the site to sit over. The design takes the form of contrasting bright whites, warm tints and yellow highlights. Clicking through enables users to read original hand-written letters that have been preserved, but also usability has been well-thought-through, with the useful addition of being able to listen to audio of the letters being read.

The site features an impressive design and it also scales down beautifully to work responsively. When on the smaller devices, swipe gestures are used extensively to enable users to browse and navigate through the content in a way that feels like a native app, tapping into the natural mental mode of users on those devices.


1. Create the expanding images

In A State of War there is a panel of images that expand as the mouse rolls over them, in order to create the same effect add the div content from FileSilo to your page. You can place images inside the expander divs.

2. Start the CSS

To position the elements correctly add the CSS from FileSilo for this step for the container that will hold the array of images for expanding outwards. This places it in the middle of the page both horizontally and vertically.

3. The rollover trigger

The next CSS is almost the same as the container. The difference here is that this is positioned at a higher z-index. This will trigger the rollover effect on the images, in this case it will simply be grey coloured panels.

#over {
height: 300px;
width: 300px;
position: absolute;
margin: 0 auto;
transform: translate(-50%, -50%);
top: 50%;
left: 50%;
z-index: 300;}

4. Each image holder

The expander class just makes grey coloured panels, but if you’ve put images in there then there is no need to add the background colour and the likelihood is that the width and height might be different. These will be positioned in a slight circle with JavaScript later.

.expander {
background: #333;
width: 200px;
height: 200px;
position: absolute;}

5. Start the JavaScript

Before the closing body tag, add the following code which links up the CDN version of jQuery library, and then in the script tag that follows a number of variables are declared. The r value holds the radius of the panels at the start, the hover holds the radius when rollover occurs.

<script src=""></script>
var theta = 0;
var r = 100;
var hover = 200;
var photos = [];

6. Circular layout

The panels are arranged in a circular layout by targeting each class of expander on the page. The position on the x and y axis is worked out using Pythagoras’ theorem for both the initial position and the hover. The panel is positioned and an object stores both positions.

$(".expander").each(function () {
var posx = Math.round(r * (Math.cos(theta)));
var posy = Math.round(r * (Math.sin(theta)));
var nx = Math.round(hover * (Math.cos(theta)));
var ny = Math.round(hover * (Math.sin(theta)));
var out = { top: posy + 'px', left: posx + 'px'};
var p = new Photo($(this), posx, posy, nx, ny);

7. Roll over the panels

When the mouse rolls over the panel that’s over the top, the for loop will loop through each panel and animate to its new position by calling its end x and y position. This is done over a duration of half a second.

$("#over").mouseover(function () {
for (i = 0; i < photos.length; i++) {
top: photos[i].endy + 'px',
left: photos[i].endx + 'px'
}, 500);}

8. Roll out

Similar to the previous code, when the mouse rolls out a for loop will loop through each of the panels and animate the panels back to the original starting position. Again this is done over the duration of half a second.

}).mouseout(function () {
for (i = 0; i < photos.length; i++) {
top: photos[i].starty + 'px',
left: photos[i].startx + 'px'
}, 500);}

9. Store positions

The photo function is an object that many new instances are made from, one for each panel. The unique starting and ending positions are stored here as a reference to which panel these belong to. Save the code and test this in the browser to see the rollover effect in action.

function Photo(obj, startx, starty, endx, endy) {
this.startx = startx;
this.starty = starty;
this.endx = endx;
this.endy = endy;
this.obj = obj;} </script>