Joel Sutherland

Creating a Minimal Blog Design Using HTML5, CSS3 and jQuery

in and

html5 blog design

A zip of this project is at the end of the post.

Redesigning this blog was a long time coming. I had started blogging on my personal site in late 2008 on Posterous, but quickly slowed and then stopped posting when my focus turned to my company blogs (New Media Campaigns, GetHiFi).

In restarting my personal blog, I had some goals that I wanted to achieve with the design:

  • Minimal in appearance and code
  • Uses modern web development techniques
  • Takes advantage of HiFi, our new CMS

The net result is something I am fairly proud of.  This site certainly isn't complicated, but it features a number of fun technologies:

  • HTML5
  • @font-face
  • CSS3
  • jQuery
  • HiFi

This post is meant to be both a tour of the site and a how-to.  So without rambling on too much further, lets begin:

The Design

I initially put together the design in photoshop.  The bars at the top are a reference to the New Media Campaigns logo.  The font I am using for the headlines is Bergamo. For body copy, I am using a Helvetica/Arial stack.

The page width is 600 pixels, which is my preference for content, especially blogs.  This is a super handy size because it is an appealing width to read and it fits nicely into most grids.  Should I ever redesign again, or migrate my content, I won't need to worry quite as much about sizing issues.

Finally, I kept the navigation really simple.  I hid nearly all of the blog gorp in an expanding menu that appears when you click the 'blog' link. This was probably the design's most opinionated decision. While this certainly hurts the discoverability of content, I'm not out to make a web portal.  It's a blog.  Generally visitors will either be following via RSS or arriving via Google/Twitter/Whatever to view a particular article.  The 99% case is to make the site as readable as possible. This is also why I used a vertical typographic grid, which I will describe later.

The Markup

Minimalism was a goal for the design; extreme minimalism was a goal for the markup.  Below is the markup for a post.  The listing page is the same, but there aren't comments and the articles are stacked.  Notice how I've tried to eliminate as much non-semantic stuff as possible. My only "sin" is a container div.  The bars at the top and other embellishments were loaded via JS.

<!DOCTYPE html> 
<html lang="en"> 
<head> 
	<meta charset="utf-8" /> 
	<title>Title</title> 
	<!-- styles -->
</head> 
<body> 
<div id="container"> 
	<header role="banner"> 
		<h1><a href="/">joel sutherland</a></h1> 
	</header> 
	<nav> 
		<ul> 
			<!-- nav items -->
		</ul> 
	</nav>
 	<div id="blog" class="hidden"> 
		<-- blog dropdown -->
	</div><!-- blog --> 
	<article> 
		<header> 
			<h1><a href="">Post Title</a></h1> 
			<div class="postmeta"> 
				<time datetime="">December 31st, 1969</time> 
				<a href="y#comments" class="comments">0 Comments</a> 
			</div> 
		</header> 
		<!-- content -->    
		<aside class="comments" id="comments"> 
			<!-- comments -->
		</aside><!-- comments --> 
	</article> 
</div><!-- container --> 
<!-- scripts --> 
</body> 
</html>

I really like the way this came out.  It made me realize the potential that HTML5 has with its new elements.  Markup is becoming much more terse and readable these days.

The CSS: Layout

Again, when it came to the CSS I was also trying to consider minimalism.  To me, this generally means avoiding images when possible and also making sure that you don't end up repeating yourself too much.  CSS that is copied and pasted is bound to give you problems later.

This site came out very well when it came to my goals with CSS.  By using cross-browser compatible gradients, box-shadows and rgba, I was able to escape with just a single image!  Here are some of the interesting highlights:

Site Background

For the background of the site, I layered my only image, a 24-bit png filled with noise over a gradient:

html {
	background: #d0cec9;
	filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#dedcd9', endColorstr='#f7f7f6');
	background: -webkit-gradient(linear, left top, left bottom, color-stop(0, rgb(222,220,217)),
 color-stop(0.1, rgb(247,247,246)), color-stop(1.0, rgb(247,247,246)));
	background: -moz-linear-gradient(top,  #dedcd9 0px,  #f7f7f6 400px, #f7f7f6 100%);
}

body {
	background: url(../images/noise.png);
}

It felt a bit dirty to use the gradient-stops to get the background to look how I wanted.  It isn't quite perfect, but that is the price I had to pay to avoid more wrapper divs.

Blog Dropdown and Blockquotes

By layering rgba backgrounds, I was able to keep both the gradients and the texture going:

blockquote {
	margin: 0 0 22px 0;
	background: rgba(0,0,0,.05);
	border-left: 4px solid rgba(0,0,0,.1);
	padding: 22px;
	font-style: italic;
}

Top-Shadow and Bars

You can barely tell, but there is a JS-generated div that is sitting just above the browser viewport.  I am applying a box-shadow to it so that the top of the page has a subtle shadow.  I am also drawing the bars entirely with JS-generated markup and CSS:

#shadow {
	position: fixed;
	top: -10px;
	left: 0;
	width: 100%;
	height: 10px;
	box-shadow: 0px 0px 7px rgba(0,0,0,.2);
	-moz-box-shadow: 0px 0px 7px rgba(0,0,0,.4);
	-webkit-box-shadow: 0px 0px 7px rgba(0,0,0,.2);
	z-index: 2;
}
#bars {
	width: 100%;
	height: 42px;
	margin-top: -20px;
}
	#bars div {
		position: relative;
		float: left;
		width: 54px;
		height: 100%;
		margin-right: 55px;
		box-shadow: 0px 2px 5px rgba(0,0,0,.35);
		-moz-box-shadow: 0px 2px 5px rgba(0,0,0,.35);
		-webkit-box-shadow: 0px 2px 5px rgba(0,0,0,.35);
	}
	#bars div.n { background: #2e78bc; }
	#bars div.m { background: #a3be48; }
	#bars div.c { background: #9a9a9a; margin: 0; }

Those are the layout highlights.  The rest is fairly run-of-the-mill.

The CSS: Type

Writing the CSS type stylesheet was a bit more fun for me since I am fairly new to vertical-grids.  I settled on a 22px vertical grid and then made sure to apply the correct styling to EVERYTHING to make it fit.  At first this sounds like a lot of work.  I was surprised at both how easy it was, and how quickly it went.  It turns out that by working within the constraint of a vertical grid, a lot of little spacing decisions end up being a lot easier.

When you're setting up your grid, a great trick is to use a background image as a guide.  Simply make an image that is 1px wide and as tall as your grid.  Leave it transparent except for the bottom pixel.  Boom, simple guideline.  As an Easter Egg, you can enable the baseline grid lines of this site by mousing over each of the bars at the top of the site.  It is best to do it on the style guide page so that you can see how it works without a random image knocking it off course.  I took the time to apply the grid to everying: from the blog drop-down, to the comments, even to the syntax highlighter.

Questionable Voodoo

So after doing quite a bit of reading, there were three tricks that people seemed to recommend adding to your stylesheet to improve legibility:

html,body { 
  text-rendering: optimizeLegibility;
  text-shadow: 0px 0px 1px rgba(255,255,255,.1);
-webkit-font-smoothing: antialiased;
}

The first line is supposed to improve kerning in Firefox. The second line adds an essentially non-visible text-shadow that triggers better anti-aliasing in Chrome/Safari on Windows.  The last one works in older versions of webkit.

I call these voodoo because I don't anticipate them having much longevity.  They don't do anything on IE -- and the other browsers will surely end up with sensible defaults that will get pushed out through auto-updates.

@Font-Face

This is a technique that allows you to embed and use essentially any font you want.  It is different from cufon and sIFR in that you're not faking anything.  You are using real browser text.  It works essentially all browsers, IE6 included. Paul Irish has developed the ideal syntax to use.

If you have a font that you want to use on a site, first make sure that its licensing permits it.  Unless you're super-careful you're probably making your font-files publicly available when you use this technique.  Adobe would not be pleased.  The next step is to go ahead and use the Font Squirrel @font-face generator.  This takes a font file, and outputs the different formats as well as CSS needed to use the font on your site. I recommend checking the 'expert' box and then requesting a Base64 encoded CSS file.  This embeds the font into the CSS file directly and saves a few HTTP requests.

Once you've gotten your @font-face CSS in place, you can use the font just like you would any other.  In my case, I'm using Bergamo for the headlines:

h1,h2,h3,h4,h5,h6 { 
	font-family: 'BergamoProRegular',georgia,serif;
	line-height: 22px;
	margin-bottom: 22px;
}

This little bit of CSS also shows the main trick to making a grid work. Give everything the same line-height and margin-bottom. When deviating, make sure it is in multiples of the grid:

h1, h1 a{
	font-size: 33px;
	color: #333230;
	line-height: 44px;
}

That's it!  If you want to see how I do the whole thing, here is a link to a non-minified version of my type CSS.

The jQuery & HiFi

Javascript was used pretty minimally on this site.  I'm a huge fan of jQuery so I was willing to spare a few KB to include the library.  I made sure to pull it from Google with the hope that visitors would already have it cached.

Bars and Shadow

The first thing I did was add in the markup I would need for the shadow and bars at the top.  Notice that I killed the padding when I added the bars.  I did this so that there would not be a weird page jump during the time between the css loading and the javascript executing:

var bars = '<div id="bars"><div class="n"></div><div class="n"></div><div class="m"></div><div class="m"></div><div class="m"></div><div class="c"></div></div>'
	$('#container').prepend(bars).css({paddingTop: 0});
	$('body').prepend('<div id="shadow" />');

Blog Dropdown

For the blog dropdown, I used some simple custom event binding.  While not strictly necessary, should I ever need to toggle the visibility of the blog panel from elsewhere, I can.

$('#blog').bind('toggle', function(){
		var $blog = $(this);
		if($blog.is(':visible')) $blog.trigger('hide');
		else $blog.trigger('show')
	})
	.bind('show', function(){
		$(this).slideDown('show');
	})
	.bind('hide', function(){
		$(this).slideUp('hide');
	});
$('#blogbutton').removeAttr('href').click(function(){
	$('#blog').trigger('toggle');
});

AJAX Search Using the HiFi API

So I won't get into the full details of this, but I will try to cover the interesting bits.  This site runs on a new CMS called HiFi. It has a unique, super-cool JSON based API built right in to it.  I used it to put the search together.  Here is the HiFi query I used.

{'type': 'page', 'content': {'like': searchphrase }}

Translated to English, this means: "Get  all pages with content containing the search phrase". HiFi has a javascript library that works with jQuery that makes it easy to use on sites.  Here is how searched and displayed the results:

var searchphrase = $('#searchbox').val();
hifi({'type': 'page', 'content': {'like': searchphrase }}).each(function(page){
	$('ul#results').append('<li>' + page.title + '</li>');
});

As soon as I get around to it, I'm going to use the API to search for all posts I have done across the three blogs I've written for.  It really is a lot of fun to work with.

Conclusion

This ended up being a bit longer than I wanted.  I think there are more lines in this post that there are lines of code running the site!  I hope it was helpful to get a look into my thoughts and the process behind the site.  If there are any questions or comments, please leave them below.

You can download a zip of the HiFi theme here.  It has all of the HTML/CSS/JS for this site.  Feel free to do anything you want with it!