Build a Basic Dribbble Fed Portfolio Website (Part 2/2)

Read the full post

Continue this step by step tutorial to create a simple single page portfolio website design that will self-update using shots from your Dribbble profile. In this second and final part of the series we’ll go through the process of building the Photoshop concept into a working HTML/CSS web page then add the jQuery plugins to pull in our Dribbble portfolio shots.

Basic portfolio website design

If you missed last week’s tutorial, this is the simple portfolio website design we’re working on. Last time we finished off mocking up the design in Photoshop, so now let’s get our hands dirty with some HTML and CSS coding.

View part one of the portfolio build tutorial

View the Dribbble portfolio website demo

So the first step towards building the fully working portfolio webpage is to export a few images from the concept. With new CSS3 properties many of the effects can be replicated in code, but we’ll still need images such as a repeating background texture.

The logo is another image that will need saving for web. Toggle off the background layer to copy in the transparency, then export this image as a PNG-24 file.

This design only needs three individual images. Thanks to the integration with Dribbble all the portfolio piece thumbnails are hosted elsewhere.

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

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


<div id="container">



The HTML page can then be started with a basic structure of Doctype and head section containing the page title, stylesheet link and Google Web Font’s stylesheet for the Droid Serif font we used in the concept. A generic container div is then added to house the centrally aligned content.

<img src="images/logo.png" alt="Chris Spooner logo" id="logo" />

<h1>Hello, I'm Chris Spooner<br>
<span>This is my super awesome self-updating Dribbble fed design portfolio</span></h1>

We can then begin copying the content from the concept into the HTML document, semantically choosing the best HTML elements for the job. The age-old “logo isn’t a H1” debate tells us the best semantic use for the <h1> element is an introductory heading, which leaves the logo in a plain <img> tag. The concept shows different sizes of text in the intro sentence. These could be included in separate H1 & H2 tags, but the sentence reads better as one element, so <span> tags can be used to provide a CSS hook instead.

<ul id="portfolio">
	<!--Dribbble feed-->	

The jQuery functionality to fetch the Dribbble shots will be saved for later, but for now an empty <ul> will work as a placeholder.

<h2>About me.</h2>
<p>I'm a creative designer, avid blogger and I'm generally crazy about pretty colours and shapes. As well as sharing tips &amp; tricks through design tutorials I also enjoy creating Call of Duty and Battlefield guides on my <a href="">YouTube gaming channel</a>.</p>

<h2>Get in touch.</h2>

<p>If you would like to talk, you can contact me by email.<br> Give it a try, I hear it’s all the rage these days!</p>

<form action="#" method="post">
		<label for="name">Name:</label>
		<input type="text" name="name" id="name" />
		<label for="email">Email:</label>
		<input type="email" name="email" id="email" />
		<label for="message">Message:</label>
		<textarea name="message" id="message"></textarea>
		<input type="submit" value="Send" id="submit" />

The next title moves on to a <h2> heading, then despite the “About Me” text being visually the same size as the H1 text in the concept, semantically it fits better in paragraph tags. CSS will be used to alter the appearance of each element to match the concept later.
A simple form is then laid out with labels, inputs and textareas. The for="" attribute adds an extra touch of usability pairs each label with its corresponding input. In the concept the textarea message box doesn’t have a label, but we should still include one in the HTML. We can simply remove it visually using CSS later.

When we view the unstyled HTML in a browser it all appears perfectly legible thanks to the semantic choices we made with our code. Even though it’s not too pretty it still features the correct hierarchy between the elements.

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: #f2f0ed url(images/bg.png);
	font-family: "Droid Serif", Georgia, Serif; 
	font-size: 24px; line-height: 48px; text-align: center;
	color: #565656;

#container {
	width: 820px; margin: 50px auto; padding: 10px;
	overflow: hidden;

With the HTML in place it can be styled up to match the concept with CSS, but first the stylesheet needs setting up with the basics. A simple reset removes any default browser styling, then the body is set up with the texture background image. The global font styling is set up to use the Droid Serif typeface, with a basic size of 24px, line-height of 48px and the grey #565656 colour.
The width of the content area in the concept comes in at 820px, which is added to the container div. It’s then centrered up using margin: 50px auto;.

img#logo {
	display: block; margin: 0 auto 50px auto;

h1 {
	font-size: 30px; font-weight: normal; margin: 0 0 30px 0;

h1 span {
	font-size: 24px;

h2 {
	font-weight: normal; clear: both;

p {
	margin: 0 0 50px 0;

a {
	color: #a65555;
	a:hover {
		color: #792626;

Working from top to bottom the content can then be styled up to match the concept. The logo image is centered and given 50px bottom margin, then the various font sizes are set on the headers. Headers by default are bold, so the font-weight: normal; declaration helps reset this.

label {
	float: left; margin: 0 15px 30px 0;
	label[for=email] {
		margin: 0 15px 0 20px;
	label[for=message] {
		display: none;

We’ll skip the portfolio section for now and return to it once the jQuery code is in place, so next up is the contact form. CSS attribute selectors can be used to target specific labels in order to adjust the margin on the Email label and hide the Message label.

input {
	width: 274px; height: 44px; padding: 3px 15px 0 10px;
	float: left;
	background: #f9f9f9; border: 1px solid #dedede;
	box-shadow: inset 0px 3px 5px 0px rgba(0, 0, 0, 0.1); 
	-moz-box-shadow: inset 0px 3px 5px 0px rgba(0, 0, 0, 0.1);
	-webkit-box-shadow: inset 0px 3px 5px 0px rgba(0, 0, 0, 0.1);
	font: 20px "Droid Serif", Georgia, Serif; color: #7d7d7d;

textarea {
	width: 788px; height: 210px; padding: 15px; margin: 0 0 20px 0;
	background: #f9f9f9; border: 1px solid #dedede;
	box-shadow: inset 0px 3px 5px 0px rgba(0, 0, 0, 0.1); 
	-moz-box-shadow: inset 0px 3px 5px 0px rgba(0, 0, 0, 0.1);
	-webkit-box-shadow: inset 0px 3px 5px 0px rgba(0, 0, 0, 0.1);
	font: 20px "Droid Serif", Georgia, Serif; color: #7d7d7d;

The input and textarea elements can then be styled up according to the concept. The original design of the form fields is quite visual with the inner shadow and border effects, but they can all be replicated with CSS, using properties such as box-shadow for the inner shadow effect.

input:focus, textarea:focus {
	background: #fff; border: 1px solid #c6c6c6;

input#submit {
	width: 136px; height: 57px; float: right; clear: both; cursor: pointer;
	background: #585858 url(images/btn-bg.png); border: none;
	box-shadow: 0px 0px 10px 0px rgba(0, 0, 0, 0.4);
	-moz-box-shadow: 0px 0px 10px 0px rgba(0, 0, 0, 0.4);
	-webkit-box-shadow: 0px 0px 10px 0px rgba(0, 0, 0, 0.4);
	font-size: 30px; color: #f9f9f9; 
	text-shadow: 0px 1px 6px rgba(0, 0, 0, 0.4);
	-moz-text-shadow: 0px 1px 6px rgba(0, 0, 0, 0.4);
	-webkit-text-shadow: 0px 1px 6px rgba(0, 0, 0, 0.4);

To aid usability, styling for the :focus state is added to change the colour of the form fields to white (as opposed to the slightly off-white) and the border made slightly darker when the fields are active. A range of declarations then set up the input with the ID of submit to match the concept by using the dark grey background texture image, resetting the width & height and adding various CSS shading effects on the button and text.

<script src=""></script>
<script src="js/jribbble.js"></script>
<script src="js/scripts.js"></script>

Now the CSS is in place it’s about time we set up this Dribbble integration. Dribbble does offer an API, but for those like me who aren’t too hot with their PHP it can be a little daunting. Thankfully there’s jQuery plugins such as Jribbble that also do the job and are much easier to set up. The jQuery library, the Jribbble plugin and a blank Javascript file are added to the head of the HTML file.

$(document).ready(function () {		
	$.jribbble.getShotsByPlayerId('chrisspooner', function (playerShots) {
	    var html = [];
	    $.each(playerShots.shots, function (i, shot) {
	        html.push('<li><a href="' + shot.url + '">');
	        html.push('<img src="' + shot.image_teaser_url + '" ');
	        html.push('alt="' + shot.title + '"></a></li>');
	}, {page: 1, per_page: 12});

Sample Javascript code from the Jribbble readme can be used as a base for the code to activate the Jribbble plugin in our scripts file. The sample code pulls in a list of a player’s shots and includes the title as a H3 element. Some adjustment to the html.push lines removes the heading to leave a linked thumbnail image in each <li> item. The code set in the variable is then injected into the UL element with the ID of portfolio in our HTML.

ul#portfolio {
	width: 720px; margin: 0 auto 50px auto; 
	list-style: none; overflow: hidden;
	ul#portfolio li {
		float: left; margin: 20px; 
		ul#portfolio a {
			display: block; width: 200px; height: 150px;
			box-shadow: 0px 0px 10px 0px rgba(0, 0, 0, 0.1);
			-moz-box-shadow: 0px 0px 10px 0px rgba(0, 0, 0, 0.1);
			-webkit-box-shadow: 0px 0px 10px 0px rgba(0, 0, 0, 0.1); 
			ul#portfolio a:hover {
				box-shadow: 0px 0px 10px 0px rgba(0, 0, 0, 0.2);
				-moz-box-shadow: 0px 0px 10px 0px rgba(0, 0, 0, 0.2);
				-webkit-box-shadow: 0px 0px 10px 0px rgba(0, 0, 0, 0.2); 

Testing the webpage in a browser shows the Dribbble shots being pulled into the page, but they’re currently being added as unstyled list elements. The final few CSS declarations float the LI items side by side and a touch of box-shadow creates a shadow effect that increases on hover.

View the Dribbble portfolio website demo

This leaves our little portfolio website project complete as a fully working webpage that automatically updates itself with Dribbble shots. Check out the demo to see it in action.

View the Dribbble portfolio website demo

  • 187
100 HD Blurred Backgrounds

Join the mailing list to have new content delivered straight to your email inbox. Every subscriber gets a free pack of 100 HD Blurred Backgrounds + bonus 10 realistic web shadows.

100 HD Blurred Backgrounds

Written by Iggy

Iggy is a designer who loves experimenting with new web design techniques collating creative website designs. You can follow Iggy on Twitter.


  1. Li Ming says:

    Nice article, although I would still prefer my website to be a bit more flashy, haha.

  2. Norvik says:

    Thanks for the tutorial!

  3. great tutorial Chris!

  4. Sonusmac says:

    Very nice article! Thanks I'm just waiting to get drafted :))

  5. Chris says:

    Nice idea and it works really well, however, I would probably add a simple link to your dribbble page as a sort of backup just incase JS is disabled.

  6. Adam says:

    Nice! What's left to do is add a dash of CSS and Voilà! Thanks Chris

  7. Creativr tutorisl i get here thanks.

  8. Very nice article. Keep going on…

  9. Such an awesome tutorial, Chris! I personally like the simple one page layout for a portfolio. Keep up the awesome work! :)

  10. Danny says:

    Great post Chris.

    I believe it is important to keep page layouts clean and tidy.

    Readers don't want to trawl through websites and be navigated all over the place.

    You stated some useful points here, I look forward to future posts!

  11. Timony says:

    Much easier version/approach for this is just use Behance (which gets more visibility these days anyways), and then use their prosite-thingamagig to bring projects into your own website.

    only reason is 400px probably won't cut it as a portfolio, no!?

  12. Now I just need to take some dribbble shots :P

  13. tangz989 says:

    Great tutorial Chris!

  14. John says:

    Really interesting way to pull stuff from dribble for the auto updates!

Leave a response