Coding a Responsive Resume in HTML5/CSS3

Almost everybody in the business section has created a resume at some point. When working as a freelancer you are always vying to land new projects. Because of this transitory work cycle it helps to offer potential clients a brief peek into your past experience. And what a better opportunity than offering your professional resume online?

In this tutorial I want to demonstrate how we can build a responsive single-page resume layout. I’ll be coding everything in HTML5/CSS3 to work properly at various screen resolutions. The resume will also support microdata powered by for more technical SEO advantages.

Building the Document

I’m starting the webpage with an HTML5 doctype and standard meta elements. But to get this layout responsive we’ll need to setup some additional components. Most of these are typical meta tags and will be supported in all modern-day browsers.

<!doctype html>
<html lang="en">
  <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
  <title>Online Responsive Resume Demo</title>
  <meta name="author" content="Jake Rocheleau">
  <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
  <meta name="HandheldFriendly" content="true">
  <meta name="viewport" content="width=device-width, initial-scale=1,maximum-scale=1,user-scalable=no">
  <link rel="stylesheet" type="text/css" href=",900|Balthazar">
  <link rel="stylesheet" type="text/css" href="styles.css">
  <link rel="stylesheet" type="text/css" href="responsive.css">
  <!--[if lt IE 9]>
    <script src=""></script>
    <script src=""></script>

The meta viewport tag is crucial for getting the responsive technique to work on smartphones. We reset the scale as 1:1 so the layout is displayed pixel-perfect. You’ll also notice I have included an external stylesheet from Google Web Fonts. I’m using two custom typefaces “Simonetta” and “Balthazar”. Unique fonts certainly grab your visitor’s attention and fit harmoniously into a single-page design.

I have also setup a small IE conditional which includes some open source scripts for legacy browsers. Internet Explorer 8 and older have issues rendering HTML5 elements and CSS3 media queries. But thankfully some smart developers have figured out how to get these working through JavaScript.

Main Content Blocks

The whole document is wrapped in a div with many various block sections inside. The top <header> tag includes my photo, name, e-mail address, and other important metadata. Afterwards I’ve broken each block into a <section> element for the rest of the content.

As you resize the page these block elements fall beneath each other gracefully. I’ve setup a few different instances of media queries in an external stylesheet. This makes it easier keeping track of styles when going back to edit something later.

<header class="clearfix">
	<div id="info">			
	    <h1><span itemprop="name">Jake Rocheleau</span></h1>
	    <h3><span itemprop="jobTitle">Freelance Writer & Web Developer</span></h3>
	    <small itemprop="address" itemscope itemtype="">
	      <span itemprop="addressLocality">Hudson</span>, 
	      <span itemprop="addressRegion">Massachusetts</span>, 
	      <span itemprop="addressCountry">USA</span>
	    <small><span itemprop="email"></span></small>
	    <small><a href="" itemprop="url">My Portfolio</a> • <a href="" itemprop="url">@jakerocheleau</a></small>
	<div id="photo">
	    <img src="" alt="Jake Rocheleau resume photo avatar" itemprop="image" />

Before we jump into detailed CSS I want to explain more about the use of microdata. If you look closely I’ve littered attributes inside many different elements with the names itemtype, itemscope, and itemprop. These all relate to the Schmea project which hopes to offer a data structure for the web.

Formatting Useful Microdata

All of the major search engines including Google, Yahoo!, and Bing have accepted Schema as the best syntax for data markup. By labeling details about yourself it helps these search engines display related results for your content online. Let’s break down how to set these up.

<div id="w" itemscope itemtype="">

The itemscope attribute is applied to any container which holds information on a schema item. This is always followed by the itemtype attribute, which in this scenario is describing a person. Inside this wrapper div I can label any content by using itemprop along with any of the details listed on their documentation page.

The recommended method is to wrap your content inside a span tag instead of appending directly to the element. When you’re labeling something like a photo you should attach itemprop to the img element directly. But otherwise you’ll have much cleaner markup by wrapping your data in span tags.

How Much is Too Much?

I would argue that there is no limit to the amount of detail you can go into. Microdata is available to help computers recognize people, organizations, products, and other items within an online context. The more information you can offer, the better.

It’s worthwhile to keep and open mind and see how you can use this microdata in aspects of your own website. If you spend 10-15 minutes going through the Schema documentation it’s a lot easier than you’d think. We can look at two solid examples from the resume demo:

<section id="skills" class="clearfix" itemscope itemtype="">
	<h2 itemprop="name">Skillset</h2>
	<section id="skills-left">
		<h4 itemprop="about">Development</h4>
		    <li itemprop="itemListElement">HTML5/CSS3</li>
		    <li itemprop="itemListElement">JavaScript & jQuery</li>
		    <li itemprop="itemListElement">PHP Backend</li>
		    <li itemprop="itemListElement">SQL Databases</li>
		    <li itemprop="itemListElement">Wordpress</li>
		    <li itemprop="itemListElement">Pligg CMS</li>
		    <li itemprop="itemListElement">Some Objective-C</li>
	<section id="skills-right">
		<h4 itemprop="about">Software</h4>
		    <li itemprop="itemListElement">Adobe Photoshop</li>
		    <li itemprop="itemListElement">Adobe Dreamweaver</li>
		    <li itemprop="itemListElement">MS Office 2007-2010</li>
		    <li itemprop="itemListElement">cPanel & phpMyAdmin</li>
		    <li itemprop="itemListElement">Xcode 4</li>

When listing my various skills I’ve setup a new container defining the ItemList schema. There wasn’t any type of skillset or experience to list under a Person, so this is a safe alternative. The value here is that Google can understand each itemListElement is related to each other. In this case we have a list of languages and software I know how to work with.

<section id="articles">
	<h2>Recent Articles</h2>
	<p itemscope itemtype="">
	<span itemprop="name">
	<a href="" itemprop="url" title="10 Useful Fallback Methods For CSS And Javascript">10 Useful Fallback Methods For CSS And Javascript</a></span> • Published in <span itemprop="datePublished">July 2012</span></p>
	<p itemscope itemtype="">
	<span itemprop="name">
	<a href="" itemprop="url" title="Rewriting URLs In WordPress: Tips And Plugins">Rewriting URLs In WordPress: Tips And Plugins</a></span> • Published in <span itemprop="datePublished">July 2012</span></p>
	<p itemscope itemtype="">
	<span itemprop="name">
	<a href="" itemprop="url" title="JPEG Optimization For The Web - Ultimate Guide">JPEG Optimization For The Web - Ultimate Guide</a></span> • Published in <span itemprop="datePublished">July 2012</span></p>
	<p itemscope itemtype="">
	<span itemprop="name">
	<a href="" itemprop="url" title="9 Tricks To Design The Perfect HTML Newsletter">9 Tricks To Design The Perfect HTML Newsletter</a></span> • Published in <span itemprop="datePublished">May 2012</span></p>
	<p itemscope itemtype="">
	<span itemprop="name">
	<a href="" itemprop="url" title="Guide To A/B Testing With Google Website Optimizer">Guide To A/B Testing With Google Website Optimizer</a></span> • Published in <span itemprop="datePublished">March 2012</span></p>

Another good example is the articles listing found at the very bottom. There is a schema setup for articles and blog posts, all related to content found online. I’ve indicated the article URL and date of publication which is more than enough info for these search engine crawlers.

Just keep in mind that microdata is all about formatting content to be organized by computers. This single-page resume is the perfect example to define traits about a specific person. These aren’t going to be useful on every website, but it’s an exciting methodology to understand.

Relative CSS Styles

In this last section let’s take a look into how to style this whole webpage. Towards the top of our stylesheet I’m defining some initial resets and basic element properties. These include headers, list items, and anchor link hover effects.

* { margin: 0; padding: 0; }
html { height: 101%; }
body { background: #f2f2f2 url(''); font-size: 62.5%; padding-bottom: 65px; }

h1 { font-family: "Simonetta", "Trebuchet MS", Arial, sans-serif; color: #454545; font-size: 3.6em; margin-bottom: 6px; }
h2 { font-family: "Simonetta", "Trebuchet MS", Arial, sans-serif; color: #484848; font-size: 2.5em; margin-bottom: 10px; text-decoration: underline; }
h3 { font-family: "Trebuchet MS", Verdana, Arial, sans-serif; color: #777; font-weight: normal; font-size: 1.8em; margin-bottom: 10px; }
h4 { font-family: "Trebuchet MS", Verdana, Arial, sans-serif; color: #656565; font-weight: bold; font-size: 1.75em; margin-bottom: 4px; }

p { font-family: "Balthazar", "Droid Serif", Times New Roman, serif; color: #565656; font-size: 1.8em; line-height: 1.4em; margin-bottom: 15px; padding-left: 35px; }
small { font-family: "Balthazar", serif; color: #656565; font-size: 1.6em; display: block; margin-bottom: 6px; }
ul { display: block; list-style: none; }
ul li { padding-left: 45px; list-style-type: none; vertical-align: top; background: url('') 25px 5px no-repeat; margin-bottom: 5px; font-family: "Balthazar", serif; color: #666; font-size: 1.6em; line-height: 2.3em; }

img { border: 0; max-width: 100%; }

a { color: #5582d6; text-decoration: none; }
a:hover { text-decoration: underline; }

Nothing too interesting except for some of the custom font stacks. I also grabbed a unique bullet icon instead of using the default “disc”. You can try searching through a directory like Icon Finder when trying to locate a similar design.

/** @group core layout **/
#w { margin: 0px 50px; padding: 20px 40px; padding-top: 35px; background: #fff; min-width: 260px; max-width: 900px; border-bottom-right-radius: 8px; border-bottom-left-radius: 8px; -webkit-border-bottom-left-radius: 8px; -webkit-border-bottom-right-radius: 8px; -moz-border-radius-bottomleft: 8px; -moz-border-radius-bottomright: 8px; }

header { width: 100%; }

/** @group personal settings **/
#info { float: left; margin-bottom: 12px; }
#photo { float: right; }
#photo img { 
-webkit-border-radius: 3px;
-moz-border-radius: 3px;
border-radius: 3px;
-webkit-box-shadow: 0 2px 4px rgba(0, 0, 0, 0.2);
-moz-box-shadow: 0 2px 4px rgba(0, 0, 0, 0.2);
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.2);
background-color: #fff;
border: 1px solid #ccc;
padding: 5px; 

There are only a few important block areas on the page which require attention. Of course the wrapper div is setup with extra margins and padding. Also the max width is limited at 900px because any larger size feels like the page has too much whitespace. I’ve also used rounded corners at the bottom of the page for a smoother effect on the eyes.

Responsive Design

Possibly the most crucial aspect of this online resume is the responsive functionality. I have five different breakpoints setup to achieve various effects when resizing the browser window.

@media only screen and (max-width: 740px) {
	h1 { font-size: 4.5em; }
	h3 { font-size: 2.2em; }
	h2 { display: block; text-align: center; }
	#info { float: none; display: block; text-align: center; }
	#photo {
		float: none;
		display: block;
		text-align: center;
	#w { padding: 20px 15px; }
	p { padding: 0; }

The initial 740px is right around where the photo image will clash with our header text. Instead of letting the photo drop-down onto the right side we clear both elements and center the whole layout. I’ve also increased the header text size to leave a more solid impact.

As the window gets smaller I have removed some extra padding from the wrapper div and paragraphs. The next problem we run into after the header is from the skills UL listing. I break down the two-column approach and instead have list items floating next to each other.

@media only screen and (max-width: 570px) {
	ul li {
		display: inline-block; 
		padding-left: 15px; 
		width: 140px; 
		background-position: -5px 0px;
		margin-right: 6px; 
		line-height: 1.7em;
	#skills-left, skills-right { margin-bottom: 15px; }

This also requires repositioning many of the default text properties. We have to update the line height and reposition each list item’s bullet icon. I’ve set a fixed width so the grid appears more organized until the next breakpoint.

Coding for Smartphones

The last three media queries are small yet very important. As you switch between landscape and portrait mode the iPhone will resize any mobile browser. This is also the case with most Android devices and Windows Mobile phones.

@media only screen and (max-width: 480px) {
	ul li { width: 120px; }
	#w { margin: 0 20px; }

@media only screen and (max-width: 320px) {
	#w { margin: 0 10px; }

/** iPhone only **/
@media screen and (max-device-width: 480px) {
	ul li { width: 150px; }

When first hitting 480px or smaller we remove some more padding from the wrapper and also re-size the list items again. Then at 320px I’ve removed some of the margin space outside the document. You can still see the textured background, but it’s not very important on such a slim vertical viewport.

Responsive online resume screenshot from iOS Mobile Safari

Lastly I’m using max-device-width to target the iPhone device itself, or namely any other mobile screen with a maximum width of 480px. In this case I want to update the list items a bit wider so that they fill in the whole screen. It will only affect the skills listings in landscape view since portrait is too skinny to notice any differences.

Final Thoughts

Working over the Internet often requires at least some type of portfolio online. When you can link to a single page resume with all your details organized together it shows that you mean business. Serious employers and potential clients will fall head over heels for such a charismatic display of professionalism in web design.

I hope you can take some key points away from this tutorial. Freelancers in any location around the world can market themselves with just a bit of technical effort. Feel free to download my demo source code above, and share your thoughts on this article in our comments area.