Line25

How to Code a Stylish Portfolio Design in HTML/CSS

Read the full post

Over on my Blog.SpoonGraphics design blog this week, I posted a Photoshop design tutorial that takes you through the process of building a stylish portfolio design concept. Follow this second part of the tutorial here on Line25, where we’ll code up the design into a fully working HTML and CSS website. Stick around for part three, when we’ll go a step further and convert the static website into a WordPress build.

The design concept

View the Photoshop tutorial

If you missed the post on Blog.SpoonGraphics, head over to find out how this design was put together in Photoshop. When you’re ready, continue on to start part two: The HTML and CSS.

View part one: Creating the PSD concept

Exporting the image graphics

Before coding up the website, we need to export a series of image graphics from the Photoshop concept. Start by making a selection of the background texture and saving it as a PNG file. This will be used to repeat across the body of the web page.

Another image that needs to be exported is the logo. This image will overlap the header area, so we need to make it a PNG-24 file to make use of Alpha Transparency.

Toggle off the text and button layers from the header and export a selection of the grey background. This image will be used as a background image in the header’s CSS.

A selection across the content area right up to the 960px guides will repeat so the content area can be as long as required.

Once all the interface graphics have been exported it’s time to move on to setting up the actual web page documents.

The HTML structure

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>Chris Spooner Design Portfolio</title>

<link href="style.css" rel="stylesheet" type="text/css" media="screen" />

</head>

<body>
	<div id="container">

	
	</div>

</body>

The HTML page begins with a typical document structure comprising of the Doctype, head and body. A link to the CSS stylesheet is added and the document content starts with a container div to enclose all the following elements.

<p id="logo"><a href="#"><img src="images/logo.png" alt="Chris Spooner logo" /></a></p>

<ul id="nav">
	<li><a href="index.html">Home</a></li>
	<li><a href="about.html">About</a></li>
	<li><a href="portfolio.html">Portfolio</a></li>
	<li><a href="contact.html">Contact</a></li>
</ul>

<div id="header">
	<h1>Hello, I'm Chris Spooner.</h1>
	<h2>I craft websites that are beautiful on both the inside and out.</h2>
	
	<p class="btn"><a href="portfolio.html">View my portfolio</a></p>
</div>

Despite the navigation coming first in the concept, we’ll add the logo first in the HTML document to keep everything structured. The logo is added as a <p> element, the navigation items as an unordered list and the intro headings as <H1> and <H2> elements.

<div id="content">
	<h3>About Chris Spooner</h3>
	
	<p>I earn a living by creating custom brands and logo designs from scratch, as well as designing and building high quality websites and blogs, but I also enjoy producing the odd t-shirt graphic, illustration or character design. I pride myself in having the nerdy skills to build top notch creations online, as well as being knowledgeable in the print side of design.</p>
	
	<h3>My latest work</h3>
	
	<p>I’m forever creating design work for both myself as personal projects and as a hired gun for clients from around the world. Here’s a few of my most recent works.</p>
	
	<div class="portfolio-item">
		<a href="#"><img src="images/portfolio-1.jpg" alt="View more info" /></a>
		<p class="btn"><a href="#">See more</a></p>
	</div>
	
	<div class="portfolio-item">
		<a href="#"><img src="images/portfolio-2.jpg" alt="View more info" /></a>
		<p class="btn"><a href="#">See more</a></p>
	</div>
	
	<div class="portfolio-item">
		<a href="#"><img src="images/portfolio-3.jpg" alt="View more info" /></a>
		<p class="btn"><a href="#">See more</a></p>
	</div>
	
	<div class="portfolio-item">
		<a href="#"><img src="images/portfolio-4.jpg" alt="View more info" /></a>
		<p class="btn"><a href="#">See more</a></p>
	</div>
	
</div>

<div id="footer">
	<p id="copyright">&copy; Chris Spooner / SpoonGraphics (Please don’t steal my work)</p>
	<p id="back-top"><a href="#">Going up?</a></p>
</div>

The ordering of the headings continues as the next level is a <H3>. The main body copy is then added within the content div, followed by a series of divs containing portfolio project thumbnails. In the final WordPress theme each of these items will be created as an individual ‘post’. The page is then finished off with a footer area which contains a copyright notice and back to top link.

Full annotated HTML

Here’s an overview of the full HTML page, complete with handy annotations and notes:

View the annotated HTML

The CSS Styling

body, div, h1, h2, h3, h4, h5, h6, p, ul, ol, li, dl, dt, dd, img, form, fieldset, input, textarea, blockquote {
	margin: 0; padding: 0; border: 0;
}

body {
	background: #f2f0eb url(images/bg.png);
	font: 16px Helvetica, Arial, Sans-Serif; color: #636363; line-height: 24px;
}

#container {
	width: 960px; margin: 0 auto;
}

#logo {
	margin: 10px auto 0 auto; position: relative; width: 183px;
}

The CSS file begins with a simple reset to remove the browser defaults, then we can start adding global styling to the body. First the background texture image is added followed by the general font styling for the page. The container div is given its 960px width and margin: 0 auto; used to centre it up on the screen. Our logo can then be positioned centrally with the same margin: 0 auto; declaration.

ul#nav {
	width: 940px; list-style: none; overflow: hidden; margin: -134px auto 25px auto;
}
	ul#nav li {
		width: 126px; height: 33px; float: left; padding: 13px 0 0 0;
		background: url(images/nav-bg.png);
		font-weight: bold; text-align: center; text-transform: uppercase;
	}
		ul#nav li:nth-child(1) {
			margin: 0 60px 0 0;
		}
		ul#nav li:nth-child(2) {
			margin: 0 316px 0 0;
		}
		ul#nav li:nth-child(3) {
			margin: 0 60px 0 0;
		}
		ul#nav li:nth-child(4) {
			margin: 0;
		}

		ul#nav li a {
			color: #616369; text-decoration: none;
		}
			ul#nav li a:hover {
				color: #a12121;
			}

The navigation menu needs a range of properties to convert the basic list into a layout that resembles the concept. The whole <ul> is first moved upwards to overlap the logo using negative margin, then each <li> is given specific dimensions, a background image and font styling to match the PSD. In order to match the layout of the concept, the CSS3 :nth-child(); selector is used so different margins can be added to each of the four list items.
Some basic styling to the anchors finishes off the navigation menu.

#header {
	height: 244px; padding: 52px 0 0 57px;
	background: url(images/home-header.jpg);
}

	#header h1 {
		font: 38px Georgia, Serif; color: #f2f0eb; letter-spacing: 2px; margin: 0 0 20px 0;
		text-shadow: 0px 3px 3px #494949;
	}
	#header h2 {
		width: 510px; font: 30px Georgia, Serif; color: #f2f0eb; letter-spacing: 2px; margin: 0 0 20px 0;
		text-shadow: 0px 3px 3px #494949;
	}
	#header p.btn a {
		display: block; width: 225px; height: 50px; overflow: hidden;
		background: url(images/home-header-btn.jpg); text-indent: -9999px;
	}

The header area makes use of the grey background image, so an exact height is added to match the dimensions of this image. Padding then helps move the text elements away from the edge and into position to match the concept. Each of the headers is then given a range of CSS font styling to match the text as Georgia with increased tracking. The drop shadow effect from Photoshop can be replicated with text-shadow while a width on the H2 will force the long sentence to wrap.
The paragraph element with the btn class can then be converted into a button style graphic using simple CSS image replacement to show the graphic in place of the default HTML wording.

#content {
	background: url(images/content-bg.png) repeat-y;
	padding: 57px 69px 50px 69px; overflow: hidden;
}
	#content h2 {
		font: 30px Georgia, Serif; letter-spacing: 2px; margin: 0 0 20px 0;
	}

	#content h3 {
		font: 26px Georgia, Serif; letter-spacing: 2px; margin: 0 0 20px 0;
	}
	
	#content p {
		margin: 0 0 30px 0;
	}
	
	#content a {
		color: #a12121; text-decoration: none;
	}
		#content a:hover {
			color: #671111;
		}
	
#content .portfolio-item {
	width: 182px; padding: 4px; background: #eee; text-align: center;
	float: left; margin: 0 7px 14px 7px;
}
	#content .portfolio-item p.btn {
		margin: 0;
	}
	#content .portfolio-item p.btn a {
		display: block; width: 183px; height: 29px; padding: 7px 0 0 0;
		background: url(images/see-more-bg.png);
		font-weight: bold; text-align: center; text-transform: uppercase;
		text-decoration: none;
	}

Next up is the main content area. This is first given the repeating background image to fill the whole area with white. Padding then pushes the content away from the edges to match the original design. overflow: hidden; is added to the content div to make sure all floats contained within the div are cleared so they don’t break the layout.
Simple styling is added to the content that makes up the body copy, including headers and paragraph elements. Then the portfolio thumbnails are styled up. These portfolio items are given the light grey background and floated side by side, then the anchor links inside these divs are styled as buttons using a PNG background image.

#footer {
	background: url(images/footer-bg.png) no-repeat; padding: 40px 0 0 0;
	overflow: hidden; margin: 0 0 30px 0;
}
	#footer p#copyright {
		font-size: 12px; float: left; margin: 0 0 0 30px; color: #b8b6b2;
	}
	#footer p#back-top {
		font-size: 12px; float: right; margin: 0 30px 0 0;
	}
		#footer a {
		color: #a12121; text-decoration: none;
	}
		#footer a:hover {
			color: #671111;
		}

The bottom of the page is then finished off with the footer div. The bottom edge of the content area is added as a background image to the footer, then padding is used to push the footer content down below the image. no-repeat is added to the background image to make sure the graphic only appears once. The copyright and back to top links are given basic font styling and floated to the left and right to position them at either sides of the page.

Browser testing

A quick test in the most common browsers shows no problems with Firefox, Safari and Chrome, but as always Internet Explorer has problems. The CSS3 :nth-child(); selectors used in the navigation menu aren’t supported by IE, but instead we can use jQuery to help with a fix.

$(document).ready(function() {
	$("ul#nav li:nth-child(1)").css("margin-right", "60px");
	$("ul#nav li:nth-child(2)").css("margin-right", "316px");
	$("ul#nav li:nth-child(3)").css("margin-right", "60px");
	$("ul#nav li:nth-child(4)").css("margin-right", "0px");
});

To fix this, we just need to use jQuery to add the relevant margins. When the same CSS is applied with jQuery Internet Explorer has no problem implementing it.

Finishing up the inner pages

Now the homepage is complete, we can continue building the inner pages of the site. The overall structure of the pages is roughly the same, with just a shortened header and different content on each.

<div id="header" class="page">
	<h1>About Chris Spooner</h1>
</div>

To style up a different header, we can simply add a class to the header of the inner pages, then give this particular header a smaller size and the plain background image.

We’ve already created the code for the portfolio items, so this can simply be duplicated for each new design project. All that needs changing is the thumbnail image.

On the contact page the form can be styled up using tips from my recent HTML5/CSS3 contact form tutorial. Just adjust the dimensions of the fields and the colours and the form design is all set.

#content #social {
	width: 371px; float: left; 
}		
	#content #social ul {
		list-style: none;
	}
		#content #social ul li {
			float: left; margin: 0 20px 20px 0;
		}
			#content #social ul li a {
				display: block; width: 100px; padding: 5px 0 5px 45px;
				background: url(images/social-icons.png) no-repeat;
			}
				#content #social ul li a.twitter { background-position: 0 -3px; }
				#content #social ul li a.youtube { background-position: -172px -1px; }
				#content #social ul li a.facebook { background-position: -172px -136px; }
				#content #social ul li a.flickr { background-position: 0 -71px; }
				#content #social ul li a.digg { background-position: -172px -71px; }
				#content #social ul li a.lastfm { background-position: 0 -140px; }

The contact form and social links are enclosed in their own divs so they can be floated side by side. Then the social links are laid out with another unordered list. A sprite image is added as the background as this contains every single icon. All you need to do is adjust the background-position so the correct icon appears next to each of the links.

The final portfolio website demo

View the portfolio website demo

Now all the pages are in place the portfolio website design concept is complete. Stay tuned for the next tutorial where we’ll convert the static HTML and CSS design into a fully working WordPress theme.

View the portfolio website demo

Free web shadows pack for every subscriber

Join the mailing list to have new content delivered straight to your email inbox. Every subscriber gets a free pack of realistic web shadows.

Written by Chris Spooner

Chris Spooner is a designer who loves experimenting with new web design techniques collating creative website designs. Check out Chris' design tutorials and articles at Blog.SpoonGraphics or follow his daily findings on Twitter.

  • http://www.alalawa.com/ idris

    this is really awesome
    thank you for sharing such a useful tutorial

    • http://twitter.com/chrisspooner Chris Spooner

      Thanks, glad to hear you enjoyed it!

  • Garth

    Hey man, this isn't a criticism but I'm just wondering why you wrap your links in p tags? Seems unnecessary to me; couldn't the "btn" class just be on the <a>?

    • http://twitter.com/chrisspooner Chris Spooner

      I just work on the practice that every inline element should be enclosed within a block element.
      It's just habit really.

      • Garth

        Oh yup fair enough, I guess I usually just display:block on my buttons. Each to their own. It must a be a little bit annoying having everyone pick your code apart, as has happened below my comment…

  • http://robcubbon.com/blog Rob Cubbon

    Really great tutorial, Chris. I didn't know about the CSS3 :nth-child(); function – I would have applied a different id or class to the li elements but your way keeps the HTML cleaner.

    • http://twitter.com/chrisspooner Chris Spooner

      Yeah :nth-child() is a life saver. IE's problems can come back to bite you but that line of jQuery soon patches it up.

  • http://wolfiezero.com/ Neil Sweeney

    Very good post, but just to add a thought. With portfolio items in theory the portfolio could be better places as a list.

    Two reasons:
    1. You call each div a "portfolio-item", which suggests the are itemised
    2. You are listing a group of similar things.

    This suggests that semantically you are better off putting them in a ul. Also, it means you only need reference a class once for the whole ul rather than for each div (which also have no semantic meaning).

    Not to say your method is wrong at all, just I'm anal about front-end code and feel they are better off listed.

    Thanks.

    • http://twitter.com/chrisspooner Chris Spooner

      I actually had this conversation with myself when building it. I came to the conclusion that using Divs would match how posts are usually outputted with WordPress (for when I convert it into a theme later).

      Thinking about it more in depth now, there probably wouldn't be any reason why WordPress posts couldn't be outputted in <li>'s.

      Will have to tweak that before I build the theme.

  • http://www.gonzodesign.com Gonzo the Great

    Hi Chris,

    nice tut, like it! Thanks for publishing this stuff.

    One thing's on my mind though .. why do you use a HTML5 doctype but write the rest of the source-code as HTML4.01? (e.g. <div id="footer'> instead of <footer>).

    Just wondering? Cheers & Ciao ..

    • http://twitter.com/chrisspooner Chris Spooner

      There's no reason not to use it really. Pros = It's shorter and cleaner, plus you could use elements like <footer> if you go the extra step to fix up older browsers.
      Cons = None. All the elements and tags have the same syntax and work the same. (Even <div id="footer">)

      Also, I can't remember exactly, but I'm sure there's something in WordPress that doesn't validate unless you use the HTML5 doctype. I'll have to rack my brains to remember what it was.

      • http://www.gonzodesign.com Gonzo the Great

        Thanks for your reply!

        Maybe an idea for me too, cause thinking about it, you're quite right that there is no reason NOT to use the HTML5-doctype ..(BTW: Checked it on IE7 & 8, and yep, works just fine!)

        So, thanks for the advice, Cheers & Ciao ..!

  • http://www.twitter.com/im_zeeshan Zeeshan Siddiqui

    Nice tutorial. Another good example of using pseudo elements of CSS and an awesome contact form.

    • http://twitter.com/chrisspooner Chris Spooner

      Thanks Zeeshan!

  • Ruben

    On the demo page, look at your closing html tags, you messed something up there :P

    </html>>
    </html>

    • http://twitter.com/chrisspooner Chris Spooner

      Fixed ;-)

      Strangely enough there was only one closing </html> tag on my local version. Re-upload and refresh a couple of times fixed it.

  • Blake

    Chris,
    I'm a newcomer to the world of online graphics arts and website design, but I've already noticed your name around the web in many ways and places (all good though). I think this is an awesome example of your knowledge, experience, and generosity in this community. Thanks for all the great work and inspirational contributions!

  • Webdesdev

    I am waiting for the next step, converting to wordpress.

    • http://realwebdesigns.com Filipe Valente

      I agree great tutorial

  • http://www.rochelledancel.com Rochelle Dancel

    Another great tutorial!

    Thanks especially for the annotated version of your code – uber useful :)

  • http://twelvetwodesign.com Rob Russo

    Nice cross promotion between your sites. Love it! And your tutorials are great. Thanks for all the inspiration.

  • http://www.my-html-codes.com HTML Codes Dude

    Great tutorial but why didn't you just give the li elements an id? I like using nth-child pseudo selectors but it seems a little un-necessary here, especially as you need jQuery for older browsers

  • http://www.madebycube.com/ Stephen Kistner

    Thanks for another great tutorial! I like the logo at the top of the layout.

  • http://calixweb.fr calixweb

    thank you for this tuts !!

  • http://designbyarm.licensebuy.com designbyarm

    thanks you for this nice tutorial

  • http://twitter.com/Michele_Leo Leonardo D’Aubeterre

    Thanks!

    Waiting for the next tutorial about wordpress ;D!

  • Mark

    Looks like a great tut! Going to try it right now! :)

  • Zombiriro

    Can I download The Files of this tutorial?

    maybe zipped file :)

  • http://--- riccardo

    Nice tut and nice layout design! …but why using a mix of older and newer tecniques? you use :nth-child but dont use a css3 gradient.. and the same for html tags… i know there's a lack of support for browsers like our "best friend" IE (but what about html5-shiv and modernizr?).

    I love your style and your pixel precision, but what about the possibility of adapt the layout to different screen? what if someone looks at my portfolio on a smartphone?

    I hope to give you some interesting thoughts with this critics. Thank you for sharing and inspire us.

    ciao!

  • http://climbingdown.wordpress.com/ Bea Litao

    This is an awesome tutorial!

    Thank you for taking the time to screenshot how the website would actually look like from designing it in Photoshop to coding it in HTML/CSS!

  • http://blog.avangelistdesign.com Avangelist

    You're going to need to explain the wrapping the logo in a p tag, what possible benefit does that provide?

    In response to some of the comments on doctype decleration. If you haven't read the W3C schema – do so. I would also recommend reading Adactio's views on it.

  • http://twitter.com/bobmarteal bob marteal

    Thanks for the walk through. Step by step is such a great way to show the process. Every HTML tut ever should have a annotated Code view.

    Is it a conscious decision not to use other HTML5 semantic tags? Do you just find the divs have some benefit for now or the benefits don't outweigh changing your style? Thanks.

  • Webdesdev

    Guys gys leave him alone, he wrote a nice tuts and we all know these coding thing (html-5, css3). If some newbie is asking these ? it's fine to ans but you gys known everything so just leave this to your styles and wait for the next step tut :)

  • http://www.catch22marketing.com/ Cameron

    Nice Tutorial Chris. Just completed my first site using mainly html5 and css3 and generally love it – especially the speed factor.

    The client was intense about load speed. No way I could get a good looking 7KB homepage back in the day.

    Thanks again

  • http://illustrator-artwork.blogspot.com Ahmed Abbouh

    great tutorial but why you used only the HTML5 doctype ?

  • http://bolica.net Ahmed Bolica

    Chris You Rock :D Thanks Dear :))

  • Fernando Avalos

    I love your templates, i'm not an actual web designer but i'm trying to learn any tips books or things i should do? i've been getting a lot from your tuts

  • http://ashish4design.wordpress.com/ Ashish

    hi, thanks for such a gr8 tutorial!

    But, one thing I never understand that why you put the LOGO IMAGE inside a <P> tag.
    I think there was no need of this and ofcourse this is not the right way to put an image anywhere…

    May be I am wrong :)

  • http://beben-koben.blogspot.com/ Beben Koben

    cleary explanation…
    great portfolio, thanks for creativity

  • Patrick

    Nice tute set Chris, learned a lot from this and some others. Looking forward to WP portion.

  • http://www.macrodesigngroup.com/ new york web design firm

    thanks for your tutorial its so easy to make it great work

  • http://www.staff-india.com IT Outsourcing

    nice tut Chris. always doing beautiful :)

  • http://www.macromindz.com web design manchester

    The tutorial has been a great inspiration for me . I think it is one of the best ones i have seen . Keep it coming.

  • http://www.webguide4u.com Vivek Parmar

    Great tut, nicely explained.
    Know how to create portfolio layout using photoshop but did not know how to embeed html and css in it. thanks for sharing

  • Manuel Cai

    This is very helpful :)
    Thank you so much.

  • http://nordahl.me Kenneth Nordahl

    I think a modern portfolio today need to show of that the designer/dev creates an experience for the visitor regardless of the platform they use. That means that the website has to include responsive design choices with scaling solutions down to the mobile screen sizes.

  • Carolyn Lauttenbach

    I love that you took this extra step beyond the photoshop tutorial. Can't wait for Part 3 :)

  • http://www.pixelsmedia.net/ Nancy Paul

    Great information but is it friendly for SEO point of view.

  • Fangirl

    I LOVE YOU for making this tutorial! <3 by: One of Your Biggest fan!

  • http://www.digitaldesignzmedia.com Asim Craft

    Great Tutorial! Very informative and clear. If your interested, Check out my portfolio http://www.digitaldesignzmedia.com/port.html. Let me know what you think.

  • http://www.avgraphics.com.au Amanda

    Great tutorial, it's helping me to learn the code for my designs. Looking forward to trying out the wordpress part.

  • Rajesh

    hi Chris Spoone it is really nice tutorials work i learnt much from this tutorial so " Thinks " Chris Spoone

  • http://www.bina.com.tr söve

    Very nice tutorials.Thanks for sharing.

  • http://www.findferry.co.uk Find Ferry

    Nice tutorial :-) Thanks from me too :-)

  • Colin

    Hey Chris,

    Really nice tutorial. Just wondering why you decided to put your portfolio thumbnails inside <img> tags instead of adding them to the background of the anchor tags via css?

    Thanks,
    Colin

  • http://www.seandey.co.uk Sean

    And again, helped me a lot.

  • http://www.icu-india.com Web Design Agency India

    thanks for your tutorial its so easy to make it .and this is great work