Advertisement

Build An Innovative Portfolio Site Using Alternative UI/UX

by

This Cyber Monday Tuts+ courses will be reduced to just $3 (usually $15). Don't miss out.

Paul J Noble's awwward winning, uniquely designed portfolio site has caught the eye of many people, and not just clients either. Today he's going to follow up on the design stage of this tutorial, and demonstrate how it's coded up.


Step 1: What We're Making

For this tutorial the excellent ROA (Sweden) website is used as an example of a portfolio item. This site has been featured recently in Creattica and the author is not affiliated with ROA. Feel free to use your own work as portfolio items.

We're going to create an online portfolio site with a grid of images, a fixed header, text and interface elements. The mark-up will be styled so that the content fits without scrolling in nearly all users' displays and scales nicely to larger screen sizes while degrading gracefully at lower resolutions. The image grid will only show the current, active image yet will contain many more hidden images that can be viewed via page-level navigation.

Creating the HTML template and CSS will prepare us for the next part of this tutorial, where we will add the interaction layer using Javascript and bring the design to life.


Step 2: Setting up the Template

Create a new html document in your preferred text editor. Attach jQuery (1.4.2+) and a new blank CSS file.

First markup we'll create will be a div that holds all our content. We'll later set minimum height and width values for this div ('#page') to ensure that the design scales at low resolutions. Create some more divs for the major elements of the page illustrated below.

<!DOCTYPE html>
	<html>
	<head>
		<title>Your Name - Digital Portfolio</title>

		<link rel="stylesheet" href="css/master.css"/>
		<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js"></script>
	</head>

	<body>	
	<div id="page">
		<div id="header"> 
			<div class="inner">
				<div id="logo"><img src="img/icons/logo.png" alt="Your Name Here"/></div>

				<div id="social"> <!-- Social media buttons --> </div>
				<div id="nav"> <!-- Global nav --> </div>	
			</div>

		</div>

		<div id="horizon">

			<div id="main">
				<div id="gallery"> <!-- The image grid --> </div>

				<div id="leftCol"> <!-- Text annotations --> </div>
			</div>

		</div>

	</div>

	</body>
	</html>

Step 3: The Header

For sites where no vertical scrolling is required, it's often less-obtrusive to place navigation and header elements at the bottom of the screen. This frees additional space at the more frequently viewed space near the top of window. We'd like this element to stretch the entire width of the user's display and always be positioned at the bottom of the screen.

Although this is visually placed at the bottom of the screen it will actually appear at the top of the document's mark-up. We'll create a div with the ID 'header' and then a nested div with the class 'inner'. An inner wrapper will simplify positioning of the internal items.

Within the wrapper we'll create three divs; '#logo', '#social' and '#nav'.

For the logo we'll nest an image file called 'img/icons/logo.png' and add some alt text. Create the logo image file by cutting your logo from the PSD. As this is going to be positioned absolutely, the exact size is not critical - however, make sure your logo image fits within the navigation bar in the design.

For the social buttons we'll require three anchors - one each for Facebook, Flickr and LinkedIn. These will have background images applied as graphics however we'll still use text for semantic purposes and hide this with CSS. For these external links we'll use the target='_blank' attribute so the pages open in a new tab or window.

For the navigation we'll again use three anchors and assign these their own classes and id values.

		<div id="header"> 
			<div class="inner">
				<div id="logo"><img src="img/icons/logo.png"/></div>

				<div id="social">
					<a class="fb" href="http://www.facebook.com/" target="_blank" title="Find me on Facebook">Find me on Facebook</a>

					<a class="flickr" href="http://www.flickr.com/" target="_blank" title="View my Flickr Photostream">View my Flickr</a>
					<a class="linkedin" href="http://www.linkedin.com/" target="_blank" title="Find me on LinkedIn">Find me on LinkedIn</a>	
					</div>

				<div id="nav">
					<a class="about" href="about" id="aboutBtn">About</a>
					<a class="photos" href="photos" id="photoBtn">Photography</a>

					<a class="workActive" href="work" id="workBtn">Work</a>		
				</div>
			</div>

		</div>

Our graphic objects for the remaining items won't be as simple as the logo. As they're interactive they'll need hover states and the navigation buttons will require active states.

For the navigation buttons we'll create an image sprite. Return to Photoshop and create a selection around the buttons in the PSD. Select Edit > Copy Merged.

Then select File > New. A dialog will appear with the width and height defaulting to the previously selected rectangle. Change the height to 3 times the default value. This will create a new canvas that will fit three versions of the navigation graphic, one for each state required; active, hover and off.

Now, move the buttons folder from the PSD and clone this group twice to create three groups. Adjust the text colours slightly to be uniform for each group to create the different button states. Below is an example of a final graphic. Save the finished version as a PNG (24-bit) to 'img/icons/nav.png' making sure the background is transparent.

For the social media buttons we'll only need two states ('hover' and 'off'). Repeat the process above to create a social media buttons image sprite. Save the image as 'img/icons/social-media.png'.

Finally, create a new image 'img/bg/header.png'.

Now that we've developed the structure and image assets, let's create some CSS to start styling this page.

At the top of the CSS file we'll include a CSS reset to ensure that no browser-specific defaults are going to mess up our layout.

	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, font, 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
	 {
		margin: 0;
		padding: 0;
		border: 0;
		outline: 0;
		font-size: 100%;
		vertical-align: baseline;
		background: transparent;

	}
	body {
		line-height: 1.2em;
		font-family: arial, sans-serif;

	}
	ol, ul {
		list-style: none;
	}
	blockquote, q {
		quotes: none;
	}
	blockquote:before, blockquote:after,
	q:before, q:after {
		content: '';
		content: none;
	}

	:focus {
		outline: 0;
	}

	ins {text-decoration: none;}
	del {	text-decoration: line-through;}

Then we'll create some base styles for the major page elements.


body, html { 
	height: 100%; }

body { 
	background: #0f1219; }
	
#page {  
	height: 100%;
	min-height: 700px; 
	position: relative; 
	min-width: 1100px;
	overflow: hidden; }
	
h1, h2, p, li,div { font-family: "arial", "helvetica",sans-serif; }
li {font-size: 12px;}

Next, we'll style the header. We'll use absolute positioning for the logo and other elements for ease of control over the design.

Note: we're going to style our anchors as block level elements ('display: block') and with negative text-indent to ensure accessible yet graphically based elements. The widths and heights may be adjusted if your custom image sprite files differ in their dimensions.

		#header { 
			background: url('../img/bg/header.png') repeat; 
			height: 60px;
			z-index: 1200;
			overflow: hidden;
		    position: absolute; bottom: 0; width: 100%; }
		
		#logo { 
			position: absolute; 
			top:0px; 
			left: 30px; }
		
		#header .inner { 
			width: auto;
			padding: 0 30px;
			position: relative;
			height: 70px; }

		#nav { 
			position: absolute;
			right: 30px;
			top: 14px;
			height: 31px;
			width: 290px;  }
			
		#nav a { 
			background: url('../img/icons/nav.png') no-repeat 0 0;  
			text-indent: -9999px; 
			float: right; 
			display: block;
			outline: none;
			height: 31px; }

Now we'll define the individual styles for each navigation button by mapping the various image sprite locations to each button's class.

			#nav a.work { 
				width: 95px;}
			#nav a.work:hover { 
				background-position: 0 -62px;}
				
			#nav a.about {  
				width: 93px;
				background-position: -188px 0;}
				
			#nav a.about:hover { 
				background-position: -188px -62px;}
				
			#nav a.workActive { 
				width: 95px; 
				background-position: -0px -31px; 
				cursor: default; }
				
			#nav a.aboutActive { 
				width: 93px; 
				background-position: -188px -31px;
				cursor: default;}
				
			#nav a.photos { 
				width: 93px; 
				background-position: -95px 0; }
				
			#nav a.photos:hover { 
				background-position: -95px -62px;}
				
			#nav a.photosActive { 
				width: 93px; 
				background-position: -95px -31px; 
				cursor: default; }

Next we'll do the same for the social media buttons.

					
					#social { 
						width: 88px; 
						height: 26px; 
						position: absolute; 
						top: 17px; 
						right: 330px; }
					
					#social a { 
						display: block; 
						background: url('../img/icons/social-media.png') no-repeat 0 0; 
						float: left; 
						height: 26px; 
						width: 26px;
						outline: none;
						float: left;
						margin-right: 4px;
						text-indent: -9999px;
						overflow: hidden; }
						
					#social a.fb { background-position: 0 0;}
					#social a.fb:hover { background-position: 0 -26px;}
					#social a.flickr { background-position: -30px 0;}
					#social a.flickr:hover { background-position: -30px -26px;}
					#social a.linkedin { background-position: -60px 0; margin-right: 0;}
					#social a.linkedin:hover { background-position: -60px -26px;}

OK, now refresh the page and you should see something similar to the image below. Hover your cursor over the buttons to see the different states. If there are any quirks in the hover states try adjusting the background-position property in your CSS.

Try resizing your browser window to simulate lower resolution displays. Scroll bars should appear once the window is reduced below the min-height and min-width values defined for the '#page' div.


Step 4: The Lighting Effects

We're going to use a spot light effect to focus visual attention on the active image while hinting at surrounding content. To create a stronger background / foreground separation we'll also apply a subtle texture pattern to the background.

To achieve this we'll need to add some mark-up. Create the following new divs nested in the div '#main'.

	<div id="main">
	
		<div class="glowBg" id="bg2">&nbsp;</div>

		<div id="glowTexture">&nbsp;</div>
		
		<div id="gallery"> <!-- The image grid --> </div>
		<div id="leftCol"> <!-- Text annotations --> </div>

		
		<div id="glowShadow">
			<img src="img/bg/glow-shadow.png" />
		</div>
		
	</div>

First let's create the spotlight image ('img/bg/glow-shadow.png') that will overlay the gallery. Returning to Photoshop, select the layer in the 'vignette' group. Go to Select > All and copy the selected region. Create a new document (it should be at least 1400 x 900) and paste the clipboard into the canvas.

Now, we'll need to make some adjustments to our image. Firstly, expand the canvas size so it is 100 pixels higher at the top.

Then, expand the left edge by 50 pixels.

Finally, expand the bottom and right edges so the total canvas size is 1600 x 1600.

Now, take the bucket tool and with anti-aliasing 'off' and tolerance set at '0', fill the transparent region around the edges with the page background color (#0f1219). The final result should look similar to the image below.

Select File > Save for Web and save this image as a 24-bit PNG ('img/bg/glow-shadow.png') with transparency enabled.

Now, returning to our original source image, select the layer Pattern Fill 1 (this is the diagonal lines layer). Right click and select 'Rasterize layer'. Then, zoom in close and select a region of the layer as below. Copy this (just the lines – don't copy the background) and paste into a new document. Save for web, again a 24-bit PNG with transparency with the path 'img/bg/lines.png'.

Now, let's add the CSS that will integrate our new images...

		#horizon { 
			min-height: 700px; 
			width: 100%; 
			overflow: hidden; }

		#main { 
			background: #0f1219;  
			width: 1300px; 
			margin: auto;  
			margin-top: -190px; 
			height:1000px; 
			overflow: hidden; 
			position: relative; }
			
		#main .inner { 
			width: 9000px; 
			height: 9000px; 
			overflow: hidden; 
			position: absolute; 
			top: 0; 
			left: 0; }
				
		.glowBg {
			background: #282d3f; 
			height: 100%; 
			width: 100%; 
			position: absolute; }	

		#glowTexture { 
			background: url('../img/bg/lines.png') repeat; 
			height: 900px; 
			width: 1300px; 
			position: absolute; 
			top: 0; 
			left: 0; } 
			
		#glowShadow {    
			height:1600px;
			position: absolute;
			width: 1500px;
			top: 00px;
			overflow: hidden;
			z-index: 200; }
			
		#glowShadow img { 
			display: block;  
			position:relative; 
			left: -100px; }

Save, refresh and you should now see the background colour, texture and spotlight. Next we'll start adding some images.


Step 5: The Gallery

For the gallery images we'll be placing images by project into columns. Each project can have multiple images arranged vertically. Different projects are accessed by moving the columns sideways.

Create a new image 640x480 and paste a snapshot of a website or crop of some work you'd like to feature. This design's darker style usually works best with images that predominately have a light background.

To begin we'll add some mark-up.

<div class="inner">

	<div class="col">
		<div class="item" style="top: 200px">
			<img src="img/work/demo-01.jpg" alt="Title 1a"/> 
		</div>

		<div class="item"  style="top: 710px">
			<img src="img/work/demo-01.jpg" alt="Title 1b" style="opacity: 0.3"/> 
		</div>

		<div class="item"  style="top: 1220px">
			<img src="img/work/demo-01.jpg" alt="Title 1c" style="opacity: 0.3"/> 
		</div>

	</div>		
	
	
	<div class="col" style="left: 660px">
		<div class="item" style="top: 200px">
			<img src="img/work/demo-01.jpg" alt="Title 2a" style="opacity: 0.3"/> 
		</div>

		<div class="item"  style="top: 710px">
			<img src="img/work/demo-01.jpg" alt="Title 2b" style="opacity: 0.3"/> 
		</div>

		<div class="item"  style="top: 1220px">
			<img src="img/work/demo-01.jpg" alt="Title 2c" style="opacity: 0.3"/> 
		</div>

	</div>
	
</div>

You'll notice we've added some inline styles on the tags. This simulates what our interaction layer will later apply automatically (we'll see how this is done in the next part of this tutorial). For the time being, however, we'll just hard-code the styles. Note: the opacity attribute will not work in Internet Explorer 8 and below.

Add the following CSS for the gallery images:

#gallery { 	 
	left: 285px;  
	position: absolute; 
	width: 100%; 
	height: 900px; }
	
#gallery .col { 
	position:absolute; 
	top: 80px; 
	width: 640px; }

.item { 
	height: 480px; 
	width: 640px; 
	background: #181a22; 
	position: absolute; 
	margin: auto; 
	top: 320px;
	z-index: 100;
	overflow: hidden; }

The most important property here is the absolute positioning of the columns (these are the divs with the class 'col'). With absolute positioning we can move each column independently or move all columns in sync, which will allow us to navigate the grid of images once the interaction layer has been applied.

Refresh the page and you should now see the gallery with images. You will note, however, that the gallery is statically positioned vertically. Ideally we'd like the content to center itself depending on the window size. To accomplish this we'll need to add a bit of scripting.

Create a new script tag just before the closing body tag and insert the following code:

<script>

var yShift = -190;
arrange()

function arrange() {

	var winHeight = $(window).height();
	
	if (winHeight > 760) {
		yShift = (((winHeight - 900)/2) - 110)
		newHeight = (winHeight - yShift)
		newHeight -=60
		$('#main').css('height', newHeight)	
	}
	
	if (yShift < -190) {
		yShift = -190;
	}
		
	$('#main').css('margin-top', yShift)
	
}

$(window).resize( function() {
	arrange()
})
</script>

Ensure jQuery has been added in the page header or else this script will not work.

This script does a few things. The arrange() function detects the window height and then adjusts the '#main' elements' CSS properties to vertically center the content. It does this in instances where the user's window is greater than 760 pixels high (see conditional at line 541), for window heights lower than this the default CSS properties are applied. The $(window).resize() listener (line 25) calls the adjust() function whenever the user's window is resized.


Step 6: Some Words

At this stage we'll add some text content relating to the active project. For this we'll need title, a sub-heading and a paragraph of text to elaborate on the active project.

Add the following mark-up to the '#leftCol' div:

<div id="projectInfo">
	<h1>Demo Project</h1>
	<p class="sub">WEBSITE 2011</p>

	<h1>Demo Project</h1>
	<p class="sub">WEBSITE 2011</p>
	<p class="body">Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nunc non tellus eget neque tempor adipiscing. Etiam neque augue, tristique eget malesuada et, luctus sed felis. In dignissim lacus eu justo tempus ut tincidunt nisi dapibus. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nunc non tellus eget neque tempor adipiscing.</p>

	<p class="link"><a href="#">Link to project here</a></p>
</div>

Of course, if you're using a real work that you've done feel free to use headings and body text that accurately describes your work.

Now we'll style this content with some additional CSS:

#leftCol { 
	padding-top: 30px; 
	width: 200px;  
	height: 480px; 
	left: 30px; 
	position: absolute;	
	z-index: 10001;  
	top: 270px; }
	
#projectInfo { 
	top: 50px; 
	position: absolute; 
	height: 350px; 
	width: 200px; }
		
#leftCol h1 { 
	color: #fff; 
	font-size: 28px; 		
	margin-bottom: 6px; 
	top: 50px; 
	font-weight: 300; 
	line-height: 30px; }
			
#leftCol p.sub { 
	color: #338966; 
	font-size: 11px; 
	text-transform: uppercase;  
	letter-spacing:2px;
	font-weight: bold; }
			
#leftCol p.body, #leftCol p.link {
	color: #8c8f95;
	font-family:  'lucida grande', 'arial';
	font-size: 12px;
	line-height: 19px;
	padding-top: 30px;
	margin-bottom: 10px; }
		
#leftCol p.link { 
	padding-top: 10px; }	
	
#leftCol p.link  a {
	color: #8c8f95;
	text-decoration: underline; }

#leftCol p.link a:hover {
	color: #fff;
	text-decoration: underline; }

Again, the most important consideration here is the absolute positioning of the '#leftCol' element. As this element is placed outside the '#gallery' tag yet within the '#main' tag, its position will be relative to the centered '#main' tag and independent of movement in the gallery. This means the text can refresh when the active project changes without changing position. The very high z-index for '#leftCol' (10001) places this content above all other content on the page. This means our text won't be interfered with by the spotlight effect. The other properties are mostly text styles and formatting related which can be adjusted as desired.

Now refresh your page and some nicely formatted text should appear to the left of the active image as illustrated below.


Step 7: Interface Elements

Now that we've developed a structure for the static content, we'll apply some mark-up that will add elements that allow our users to interact with the site.

Returning to the '#leftCol' div, add the following code:

<div id="controls">

	<div id="grid">
			
	</div>

	<div id="keys">
		<a href="#" class="kup">Up</a>
		<a href="#" class="kdown">Down</a>

		<a href="#" class="kleft">Left</a>
		<a href="#" class="kright">Right</a>

	</div>

</div>

The '#grid' element is empty; this will be populated by Javascript in the final working version. For the time being, however, we'll just hard code some child elements to get an idea of how it will appear.

<div id="grid">
	<div class="line" style="height: 55px; opacity: 0.4;">&nbsp;</div>

	<div class="line" style="height: 27px; opacity: 0.4;">&nbsp;</div>
	<div class="line" style="height: 55px; opacity: 0.4;">&nbsp;</div>

	<div class="line" style="height: 41px; opacity: 0.4;">&nbsp;</div>
	<div class="line" style="height: 41px; opacity: 0.4;">&nbsp;</div>

	<div class="line" style="height: 55px; opacity: 0.4;">&nbsp;</div>
	<div class="line" style="height: 27px; opacity: 0.4;">&nbsp;</div>

	<div class="line" style="height: 41px; opacity: 0.4;">&nbsp;</div>
	<div class="line" style="height: 55px; opacity: 0.4;">&nbsp;</div>

	<div class="line" style="height: 41px; opacity: 0.4;">&nbsp;</div>
	<div class="line" style="height: 27px; opacity: 0.4;">&nbsp;</div>

	<div id="tracker" style="height: 14px;">&nbsp;</div>
</div>

Now we're going to again use a sprites image, this time for our arrow keys. So returning to Photoshop, go to the 'keyboard' group and using the ruler tool note the total dimensions.

Again, we'll need to allow for twice the height of the group for inclusion of a 'default' and 'hover' state. Create a new document with a transparent background that's equal to the width of the 'keyboard' group and twice the height. In the tutorial example this equates to 70 x 92.

Drag the 'keyboard' group into the new document. Duplicate this group and position one immediately above the other. The group below will be our 'hover' state. Make some minor adjustments for the hover state by brightening the color overlay, arrows and outline. Fine adjustments are often sufficient for hover states and minor shifts in brightness are usually easily noticeable.

For the tutorial example, changing the background color from #262a34 to #2b2f3a and the stroke / arrow background color from #32343f to #4b4d56 will create an effect that's ideal.

The final image should look something like below:

Save this image as 'img/icons/keys.png'.

Now we'll add some CSS to map the image to the various classes.

#leftCol #controls {  
	width: 200px; 
	height: 55px; 
	position: absolute;  
	bottom: 18px; }
	
#grid .line { 
	width: 5px; 
	background: #666; 
	overflow: hidden; 
	float: left; 
	margin-right: 2px; 
	position: relative; 
	cursor: default; }
	
#grid { 
	height: 55px; 
	width: 200px; }
	
#tracker { 
	height: 10px; 
	background: #fff; 
	width: 5px; 
	position: absolute; 
	z-index: 10000;
	cursor: default; }
	
#grid .line { 
	width: 5px; 
	background: #3d424f; 
	overflow: hidden; 
	float: left; 
	margin-right: 2px; 
	position: relative; 
	cursor: default; }
	
#keys { 
	width: 92px; 
	height: 46px; 
	position: absolute; 
	left: 86px; 
	bottom: 0;  }
	
#keys a { 
	text-indent: -999px; 
	width: 22px; 
	height: 22px; 
	background: url('../img/icons/keys.png') no-repeat 0 0; 
	overflow: hidden; 
	position: absolute; }

The child '.line' elements will form a grid representing the relative column heights. This abstraction will be an ideal way of letting the user know the size of the folio, its parts and their current position – in some ways equivalent to the breadcrumb of a traditional content site.

Anyway, the next task is to map the key classes to the image sprite:

	#keys a.kup { 
	left: 24px; 
	text-indent: -999px; 
	top: 0; 
	background-position: -24px 0; }
	
#keys a.kup:hover, #keys a.hoveru { 
	background-position: -24px -46px; }
		
#keys a.kdown { 
	left: 24px; 
	top: 24px; 
	background-position: -24px -24px; }
	
#keys a.kdown:hover, #keys a.hoverd {
	 background-position: -24px -70px;
	}
		
#keys a.kleft { 
	left: 0px;  
	top:24px; 
	background-position: 0px -24px; }
	
#keys a.kleft:hover, #keys a.hoverl { 
	background-position: 0px -70px; }
		
#keys a.kright { 
	left: 46px;  
	top: 24px; 
	background-position: -46px -24px; 
	width: 24px; }
	
#keys a.kright:hover, #keys a.hoverr { 
	background-position: -46px -70px; }

Try refreshing your browser and hovering the elements just created. The new keys and grid should appear similar to the illustration below:


Step 8: Interface Elements

Finally, we'll add the dynamic navigation that will attach to the active project. Insert the following mark-up immediately after the open tag of the '#leftCol' element:

<a href="#" id="left" class="mover" style="display: none"></a>

<a href="#" id="right" class="mover" style="left: 895px; top: 240px;"></a>
<a href="#" id="down" class="mover" style=" left: 555px; top: 490px;"></a>

<a href="#" id="up" class="mover" style="display: none"></a>

We've used inline styling here to simulate what will be achieved automatically when we've added full Javascript interactivity.

Another image sprite will be used for these anchors. Returning to our Photoshop file, open the 'buttons' group and select the right angle layer. As we'd like some padding on our anchor we'll style these with the dimensions 44 x 44.

Create a new document 88 x 176 with a transparent background to accommodate 2 sets of 4 icons. Create a new layer that's black to help us see the translucent arrows. Drag a vertical guide to 44 pixels on the x-axis. (drag guides when rulers are enabled and ensure Window > Info is visible to see the current location). Then drag three horizontal guides at 44, 88 and 132 pixels on the y-axis.

Now, returning to the original PSD, drag the angle arrow into the new document and create 4 copies in the left side. This will be our 'default' state. Make the opacity for each layer 12%. Using Edit > Transform to rotate the guides such that the order is as appears below:

Copy these layers and move each exactly 44 pixels to the right. Adjust each of the new layers' opacity to 20%. Turn off the black background so that the canvas appears almost entirely transparent and select Save for Web. Export as a 24 bit PNG with transparency enabled to 'img/icons/movers.png'.

Now we'll add some CSS to map this image:

	a.mover {
		background: url('../img/icons/movers.png') no-repeat -44px 0; 
		height: 44px; 
		width: 44px; 
		outline: none !important; } 

	#up, #right, #down, #left { 
		display: block; 
		z-index: 300; 
		position: absolute;  
		top: 10px; 
		left: 10px; }

	#right {  background-position: 0px -44px; }
	#right:hover { background-position: -44px -44px; }
	
	#down {  background-position: 0 -88px;}
	#down:hover {  background-position: -44px -88px;}
	
	#up{  background-position: 0px -132px;}
	#up:hover {  background-position: -44px -132px;}

Refresh your browser and you should now see something similar to below.

And that's it! For the final part of this tutorial we'll write the Javascript that will automatically handle the layout of the images and introduce dynamic navigation using the keyboard or mouse.

In case you may have missed anything, here's the final HTML markup:

	<!DOCTYPE html>
	    <head>
	        <title>Your Name - Digital Portfolio</title>
	        <link rel="stylesheet" href="css/master.css"/>

			<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js"></script>
	 	</head>

	    <body>   
	    <div id="page">
	      	<div id="header">

			    <div class="inner">
			    	<div id="logo"><img src="img/icons/logo.png"/></div>
			    	<div id="social">

			        	<a class="fb" href="http://www.facebook.com/" target="_blank" title="Find me on Facebook">Find me on Facebook</a>
			        	<a class="flickr" href="http://www.flickr.com/" target="_blank" title="View my Flickr Photostream">View my Flickr</a>

			        	<a class="linkedin" href="http://www.linkedin.com/" target="_blank" title="Find me on LinkedIn">Find me on LinkedIn</a>
			    	</div>

			    	<div id="nav">
			        	<a class="about" href="about" id="aboutBtn">About</a>
			        	<a class="photos" href="photos" id="photoBtn">Photography</a>

			        	<a class="workActive" href="work" id="workBtn">Work</a>    
			    	</div>
				</div>

			</div>

	        <div id="horizon">

	            <div id="main">

					<div class="glowBg" id="bg2">&nbsp;</div>

					<div id="glowTexture">&nbsp;</div>

	                <div id="gallery"> 
		
							<div class="inner">

								<div class="col">

									<div class="item" style="top: 200px">
										<img src="img/work/demo-02.jpg" alt="Title 1a"/> 
									</div>

									<div class="item"  style="top: 710px">
										<img src="img/work/demo-02.jpg" alt="Title 1b" style="opacity: 0.3"/> 
									</div>

									<div class="item"  style="top: 1220px">
										<img src="img/work/demo-02.jpg" alt="Title 1c" style="opacity: 0.3"/> 
									</div>

								</div>		


								<div class="col" style="left: 660px">
									<div class="item" style="top: 200px">
										<img src="img/work/demo-03.jpg" alt="Title 1a" style="opacity: 0.3"/> 
									</div>

									<div class="item"  style="top: 710px">
										<img src="img/work/demo-03.jpg" alt="Title 1b" style="opacity: 0.3"/> 
									</div>

									<div class="item"  style="top: 1220px">
										<img src="img/work/demo-03.jpg" alt="Title 1c" style="opacity: 0.3"/> 
									</div>

								</div>
							</div>

							<!-- End Step 6 -->
					</div>
	                <div id="leftCol"> <!-- Text annotations --> 


							<a href="#" id="left" class="mover" style="display: none"></a>

							<a href="#" id="right" class="mover" style="left: 895px; top: 240px;"></a>
							<a href="#" id="down" class="mover" style=" left: 555px; top: 490px;"></a>

							<a href="#" id="up" class="mover" style="display: none"></a>


						<div id="projectInfo">

						    <h1>Demo Project</h1>
						    <p class="sub">WEBSITE 2011</p>
						    <p class="body">Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nunc non tellus eget neque tempor adipiscing. Etiam neque augue, tristique eget malesuada et, luctus sed felis. In dignissim lacus eu justo tempus ut tincidunt nisi dapibus. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nunc non tellus eget neque tempor adipiscing.</p>

						<p class="link"><a href="#">Link to project here</a></p>
						</div>


						<div id="controls">

							<div id="grid">
								<div class="line" style="height: 55px; opacity: 0.4;">&nbsp;</div>
								<div class="line" style="height: 27px; opacity: 0.4;">&nbsp;</div>

								<div class="line" style="height: 55px; opacity: 0.4;">&nbsp;</div>
								<div class="line" style="height: 41px; opacity: 0.4;">&nbsp;</div>

								<div class="line" style="height: 41px; opacity: 0.4;">&nbsp;</div>
								<div class="line" style="height: 55px; opacity: 0.4;">&nbsp;</div>

								<div class="line" style="height: 27px; opacity: 0.4;">&nbsp;</div>
								<div class="line" style="height: 41px; opacity: 0.4;">&nbsp;</div>

								<div class="line" style="height: 55px; opacity: 0.4;">&nbsp;</div>
								<div class="line" style="height: 41px; opacity: 0.4;">&nbsp;</div>

								<div class="line" style="height: 27px; opacity: 0.4;">&nbsp;</div>
								<div id="tracker" style="height: 14px;">&nbsp;</div>

							</div>

							<div id="keys">
								<a href="#" class="kup">Up</a>

								<a href="#" class="kdown">Down</a>
								<a href="#" class="kleft">Left</a>

								<a href="#" class="kright">Right</a>
							</div>

						</div>

		</div>

					<div id="glowShadow">
						<img src="img/bg/glow-shadow.png" />
					</div>

	            </div>

	        </div>

	    </div>

		<script>
		var yShift = -190;
		arrange()
		function arrange() {

			var winHeight = $(window).height();

			if (winHeight > 760) {
			yShift = (((winHeight - 900)/2) - 110)
			newHeight = (winHeight - yShift)
			newHeight -=60
			$('#main').css('height', newHeight)	
			}

			if (yShift < -190) {
				yShift = -190;
			}		
			$('#main').css('margin-top', yShift)

		}

		$(window).resize( function() {
			arrange()
		})

		</script>

	    </body>
	    </html>
Advertisement