Hostingheaderbarlogoj
Join InMotion Hosting for $3.49/mo & get a year on Tuts+ FREE (worth $180). Start today.
Advertisement

Quick Tip: Perfectly Positioned Plusses

by
Gift

Want a free year on Tuts+ (worth $180)? Start an InMotion Hosting plan for $3.49/mo.

Ever seen those thumbnails which, when hovered over, reveal an icon in the middle to suggest what's about to happen? Ever wondered how the effect is achieved? Ever tried, but didn't manage to get the icons dead center, especially when your thumbnails weren't of fixed dimensions? Then this Quick Tip is for you..


I'm talking about thumbnails which you might click to trigger a lightbox, or perhaps a thumbnail which links to a portfolio piece. In any case, it's a great addition to your site's usability if you can suggest what's about to happen when someone hovers over a thumbnail.

This Quick Tip is aimed at those of you who have an understanding of CSS, have more-or-less figured out what positioning is about, and are looking for the perfect excuse to put it to use..


Step 1: Starting Block

Let's quickly throw some documents together to demonstrate what I'm talking about. Firstly, our html:

<!DOCTYPE html>
<html lang="en">

	<head>

		<meta charset="utf-8" />

		<title>Hover Demo Thingy</title>

		<link rel="stylesheet" href="styles.css" type="text/css" />

	</head>

	<body>
	
	</body>

</html>

Then we'll begin our styles.css file with some reset rules. You may well have your own preferred reset methods, but for the time being I've used Eric Meyer's to kick-start our css:

/* http://meyerweb.com/eric/tools/css/reset/ 
   v2.0 | 20110126
   License: none (public domain)
*/

html, body, div, span, applet, object, iframe,
h1, h2, h3, h4, h5, h6, p, blockquote, pre,
a, abbr, acronym, address, big, cite, code,
del, dfn, em, img, ins, kbd, q, s, samp,
small, strike, strong, sub, sup, tt, var,
b, u, i, center,
dl, dt, dd, ol, ul, li,
fieldset, form, label, legend,
table, caption, tbody, tfoot, thead, tr, th, td,
article, aside, canvas, details, embed, 
figure, figcaption, footer, header, hgroup, 
menu, nav, output, ruby, section, summary,
time, mark, audio, video {
	margin: 0;
	padding: 0;
	border: 0;
	font-size: 100%;
	font: inherit;
	vertical-align: baseline;
}
/* HTML5 display-role reset for older browsers */
article, aside, details, figcaption, figure, 
footer, header, hgroup, menu, nav, section {
	display: block;
}
body {
	line-height: 1;
}
ol, ul {
	list-style: none;
}
blockquote, q {
	quotes: none;
}
blockquote:before, blockquote:after,
q:before, q:after {
	content: '';
	content: none;
}
table {
	border-collapse: collapse;
	border-spacing: 0;
}

Next, to give our page a bit of layout structure, here are three columns, within a container:

		<div class="wrapper">
		
			<div class="col">
			
			</div><!--end col-->
		
			<div class="col">
			
			</div><!--end col-->
		
			<div class="col">
			
			</div><!--end col-->
		
		</div><!--end wrapper-->

And now, of course, we need to add some styles to actually get them behaving as columns within a flexible wrapper:

/*our demo styles*/

html,
body {
	background: #29282e;
}

.wrapper {
	width: 90%;
	max-width: 960px;
	margin: 30px auto;
}

.col {
	width: 27%;
	padding: 0 3%;
	float: left;
}

So there we have them; three columns, each 27% wide, with padding left and right of 3%, and all of them floating neatly in a row. Our wrapper is nicely flexible at 90% of the browser window width (to a maximum of 960px). We've also given our body and html a nice, dark background color.


Step 2: Images

It's time to add some images to the mix. I've used some wallpapers from Atelier Olschinsky's rather inspiring cities collection (grab them from kuvva.com for your desktop..)

Each image is going to be contained within an HTML5 figure element, but wrapped directly by an anchor in order to link it with something (either a lightbox enlarged version, or an external site etc.):

   
			<div class="col">
			
				<figure>
				
					<a class="enlarge" href="">
					
						<img src="img/cities-07.jpg" alt="city number 7" />
					
					</a>
				
				</figure>
			
			</div><!--end col-->

So we'll place three of our figures, one for each image thumbnail, within a column of its own.

These images are too big, so to prevent them from bursting out of their columns, let's give them a maximum width by applying a classic fluid image rule:

figure img {
	max-width: 100%;
}

A good start. We have our fluid layout with three columns, each containing an image which links somewhere.


Step 3: Hover State

Let's make it clear to users that clicking the images does something. We'll add a hover state, reducing the opacity of the thumbnail:

figure a:hover img {
	opacity: 0.4; 
	filter: alpha(opacity=40); /* IE6-IE8 */
}

Step 4: Icon

Now for the all important icon. We want an icon, placed in the center of the thumbnail, to become visible when the image is hovered over. It can be whatever symbol you like, but it should indicate to the user what's going to happen. In this demonstration, for the sake of ease, I'm just going to use a + sign to suggest a larger version will be activated.

We'll add it into the mix using the pseudo element :before:

a.enlarge:before {
	content: "+";
	display: block;
	font-size: 40px;
	line-height: 1em;
	height: 1em;
	width: 1em;
	text-align: center;
	
	color: #fff;
	font-weight: bold;
	
	position: absolute;
	z-index: 100;
}

We've placed our + as a generated :before element, part of the anchor surrounding the image. We're using the class "enlarge" to identify the anchors which will need the +. If we need another symbol, we can use another class name.

To begin with we need to dictate the content (our + character) and state that it's a block level element.

Important! The following rules then determine the dimensions. We've said that the font-size is 40px. Then we've said that the line-height, the height and the width are all equal to 1em (40px therefore). This has created a square of 40x40px. By setting the text-align to center and the line-height to 1em, we guarantee that the character is sitting smack-bang in the vertical and horizontal center of our square.

The next important rules are the absolute positioning (0px,0px by default) and the z-index which determines the stacking order of our positioned elements. By setting this to 100, we can make sure our other elements sit on top of it. Let's do that now..

figure img {
	max-width: 100%;
	position: relative;
	z-index: 900;
}

figure a {
	position: relative;
	display: block;
	line-height: 0px;
	text-decoration: none;
}

Here we've made sure that the img tags are sitting on top of the + icons by setting the z-index higher than 100. In order for that to take effect we ned to state a positioning type ("relative" in this case). Our anchor also has position:relative which means the + icon is now absolutely positioned against it.

You'll also notice a few other styles added to the anchor. We've made it display as a block, removed any underline decoration, plus given it a line-height of 0px. The line-height is important and if not reset can manifest itself as additional padding at the bottom of the element. We've now made sure that the anchor fits snugly around the image.

Our icons are actually always present, but they only become visible when the image covering them is hovered over.


Step 5: Proper Positioning

At the moment, our icons are positioned as default in the top left of our anchors. We need them in the center of the thumbnails, irrespective of how big the thumbnails are. Let's then position them 50% from the left and 50% from the top. Job done, right?

a.enlarge:before {
	content: "+";
	display: block;
	font-size: 40px;
	line-height: 1em;
	height: 1em;
	width: 1em;
	text-align: center;
	
	color: #fff;
	font-weight: bold;
	
	position: absolute;
	top: 50%;
	left: 50%;
	z-index: 100;
}

Hmm. Not really. The icon's nowhere near the center of the thumbnail.. That's because elements are aligned in relation to their top left corner. Look again:

To compensate for the positioning we have to shift it half its height up and half its width left. We used ems earlier to determine the dimensions (1em = 40px), so let's now use 0.5em (half the square's width) to do the shifting. This way, whatever we change the font-size to, all the measurements will remain proportional. Thanks to Gabri for pointing out the use of ems!

a.enlarge:before {
	content: "+";
	display: block;
	font-size: 40px;
	line-height: 1em;
	height: 1em;
	width: 1em;
	text-align: center;
	
	color: #fff;
	font-weight: bold;
	
	position: absolute;
	top: 50%;
	left: 50%;
	z-index: 100;
	
	margin: -0.5em 0 0 -0.5em;
}

To do that we apply a negative margin. -0.5em on the top and on the left will do the job. Think of it as having created a vacuum, into which our element is sucked.

Bingo! Our + icon is perfectly positioned in the center of our thumbnail. Try resizing the browser, it'll stay exactly dead-center.


Why not take the effect further?

There's bags of potential for a technique like this:

  • Employ the websymbols font and jazz your icons up a bit.
  • Apply different classes to your thumbnails, depending on the icon you want to display.
  • Why not add CSS transitions to smooth the hover effect?

Conclusion

To seasoned CSS-ers this is a very straight-forward trick, but if you've never considered positioning like this before I hope this Quick Tip has been helpful.

Advertisement