A CSS Only Image Gallery With Zooming!

April 5, 2012 at 5:04 pm By
Download Demo

So today we’re going to be making an image gallery where the images zoom out on click. We’ll also add a close button for closing the images after they’ve been zoomed out. Best of all, we’re going to be doing it all with just CSS!

It’s best to keep this non-scrollable, since :target makes the page jump to the object, which would be rather annoying on a scrollable website. If you need to, we can override this with a simple line of Javascript, which you can find at the end of this tutorial.

Support

Number of Users Who Can Use
Full Demo 55.93%
Without Transitions 72.47%

Lets Begin

To start, lets take a look at the HTML. It consists of a large parent element which contains several holders, each of which act as a single image. Each holder has a few features such as a close button, an image, and a link which allows us to click the image to expand it. Each ‘expand’ link is linked to the holder parent, so that we can use :target in CSS.

<div id="images-box">
	<div class="holder">
		<div id="image-1" class="image-lightbox">
			<span class="close"><a href="#">X</a></span>
			<img src="1.jpg" alt="earth!">
			<a class="expand" href="#image-1"></a>
		</div>
	</div>
	<div class="holder">
		<div id="image-2" class="image-lightbox">
			<span class="close"><a href="#">X</a></span>
			<img src="2.jpg" alt="earth!">
			<a class="expand" href="#image-2"></a>
		</div>
	</div>
	<div class="holder">
		<div id="image-3" class="image-lightbox">
			<span class="close"><a href="#">X</a></span>
			<img src="3.jpg" alt="earth!">
			<a class="expand" href="#image-3"></a>
		</div>
	</div>
</div>

The CSS

The CSS isn’t that challenging. To begin, lets style the parent holder elements.

#images-box {
	/* The total width of the image-box, mainly for centering */
	width: 850px;
	margin: 0px auto;
	position: relative;
	top: 70px;
}

.image-lightbox img {
	/* Inherit the width and height from the parent element */
	width: inherit;
	height: inherit;
	z-index: 3000;
}

.holder {
	/* The width and height, you can change these */
	width: 250px;
	height: 166px;
	/* Float left, so everything aligns right */
	float: left;
	margin: 0 20px 0 0;
}

.image-lightbox {
	/* Inherit width and height from the .holder */
	width: inherit;
	height: inherit;
	padding: 10px;
	/* Box shadow */
	box-shadow: 0px 0px 10px rgba(0,0,0,0.1);
	background: #fff;
	border-radius: 5px;
	/* Position absolutely so we can zoom it out later */
	position: absolute;
	top: 0;
	font-family: Arial, sans-serif;
	/* Transitions to provide some eye candy */
	-webkit-transition: all ease-in 0.5s;
	-moz-transition: all ease-in 0.5s;
	-ms-transition: all ease-in 0.5s;
	-o-transition: all ease-in 0.5s;
}

Next we need to style the internal elements. I set the <span> elements to display: none so that we can make the close button appear when the user clicks on the image. The anchor has been altered to fill the entire parent element, making it all clickable.

.image-lightbox span {
	display: none;
}

.image-lightbox .expand {
	width: 100%;
	height: 100%;
	position: absolute;
	top: 0;
	z-index: 4000;
	background: rgba(0,0,0,0); /* Fixes an IE bug */
	left: 0;
}

.image-lightbox .close {
	position: absolute;
	width: 20px; height: 20px;
	right: 20px; top: 20px;
}

.image-lightbox .close a {
	height: auto; width: auto;
	padding: 5px 10px;
	color: #fff;
	text-decoration: none;
	background: #22272c;
	box-shadow: inset 0px 24px 20px -15px rgba(255, 255, 255, 0.1), inset 0px 0px 10px rgba(0,0,0,0.4), 0px 0px 30px rgba(255,255,255,0.4);
	border-radius: 5px;
	font-weight: bold;
	float: right;
}

.image-lightbox .close a:hover {
	box-shadow: inset 0px -24px 20px -15px rgba(255, 255, 255, 0.01), inset 0px 0px 10px rgba(0,0,0,0.4), 0px 0px 20px rgba(255,255,255,0.4);
}

Before we continue onto the :target stuff, some positioning is required. If you want to add more images you’ll have to add some stuff here.

div#image-1 { left: 0; }
div#image-2 { left: 290px; }
div#image-3 { left: 580px; }

The actual targeting of elements isn’t that hard. We just need to change the position and z-index, oh, and change some of the element’s display property.

div[id^=image]:target {
	width: 450px;
	height: 300px;
	z-index: 5000;
	top: 50px;
	left: 200px;
}
div[id^=image]:target .close {
	display: block;
}

div[id^=image]:target .expand {
	display: none;
}

div#image-1:target, div#image-2:target, div#image-3:target { left: 200px; }

And that’s it! Here’s the full CSS as usual, in case you just want to copy and paste. Have a good day, check out the demo, and if you feel so inclined, click that tweet button.


#images-box {
	/* The total width of the image-box, mainly for centering */
	width: 850px;
	margin: 0px auto;
	position: relative;
	top: 70px;
}

.image-lightbox img {
	/* Inherit the width and height from the parent element */
	width: inherit;
	height: inherit;
}

.holder {
	/* The width and height, you can change these */
	width: 250px;
	height: 166px;
	/* Float left, so everything aligns right */
	float: left;
	margin: 0 20px 0 0;
}

.image-lightbox {
	/* Inherit width and height from the .holder */
	width: inherit;
	height: inherit;
	padding: 10px;
	/* Box shadow */
	box-shadow: 0px 0px 10px rgba(0,0,0,0.1);
	background: #fff;
	border-radius: 5px;
	/* Position absolutely so we can zoom it out later */
	position: absolute;
	top: 0;
	font-family: Arial, sans-serif;
	/* Transitions to provide some eye candy */
	-webkit-transition: all ease-in 0.5s;
	-moz-transition: all ease-in 0.5s;
	-ms-transition: all ease-in 0.5s;
	-o-transition: all ease-in 0.5s;
}

.image-lightbox span {
	display: none;
}

.image-lightbox .expand {
	width: 100%;
	height: 100%;
	position: absolute;
	top: 0;
	left: 0;
}

.image-lightbox .close {
	position: absolute;
	width: 20px; height: 20px;
	right: 20px; top: 20px;
}

.image-lightbox .close a {
	height: auto; width: auto;
	padding: 5px 10px;
	color: #fff;
	text-decoration: none;
	background: #22272c;
	box-shadow: inset 0px 24px 20px -15px rgba(255, 255, 255, 0.1), inset 0px 0px 10px rgba(0,0,0,0.4), 0px 0px 30px rgba(255,255,255,0.4);
	border-radius: 5px;
	font-weight: bold;
	float: right;
}

.close a:hover {
	box-shadow: inset 0px -24px 20px -15px rgba(255, 255, 255, 0.01), inset 0px 0px 10px rgba(0,0,0,0.4), 0px 0px 20px rgba(255,255,255,0.4);
}

div[id^=image]:target {
	width: 450px;
	height: 300px;
	z-index: 5000;
	top: 50px;
	left: 200px;
}
div[id^=image]:target .close {
	display: block;
}

div[id^=image]:target .expand {
	display: none;
}

div#image-1:target, div#image-2:target, div#image-3:target { left: 200px; }

div#image-1 { left: 0; }
div#image-2 { left: 290px; }
div#image-3 { left: 580px; }