joel sutherland

Creating a Minimal Blog Design Using HTML5, CSS3 and jQuery

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:

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

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!

HiFi is Making Crazy Progress

hifi custom fields

There has been some great work done lately by Josh Lockhart (@codeguy), Eli Van Zoeren (@elivz)  and Kris Jordan (@KrisJordan) on HiFi.  Among 81 minor improvements launched tonight, we now have custom fields live and operational!

This won't mean much to the non-nerds out there, but it is a great achievement.  It is now possible to define a set of fields that will show up in HiFi for site editors to use.  So if you're making a Portfolio section, you can add fields for URL, Project Type, and even Images that are fully integrated with the rest of the HiFi media system.

Perhaps coolest of all, you then assign the custom fieldset to a place in your site tree.  It then will apply to that area of the site only.  Since the HiFi API is so clean, this also means that custom fields stack.

Ultimately, this is a super-flexible framework for creating a site structure that makes the most sense to end users and makes the data available to developers through a simple JSON API.  We're excited to start using this in practice!

The New JSuth.com Has Launched

The site you are seeing has been upgraded from its old existence on posterous with a default theme.  It was a lot of fun to design this and play around with some cool HTML5/JS/CSS tricks.

To check out the text styling I used, go to the Greeked Text page.  To see the typographic baseline, mouse over each of the colored bars at the top of the screen.

My goal with the design was to make something simple that looked nice.  When coding it, I also wanted to stick with minimalism.  The template only uses one image, a 24-bit noise tile for the background.  Everything else was done in CSS.  I also tried to keep the HTML minimal by using Javascript to inject non-essential elements.

I hope you like the site -- let me know if there are complains.  Expect a full-on nerdy writeup at some point in the future.

Blue Cross Blue Shield of NC Lies in its Commercial

Blue Cross Numbers Lie

The existence of misleading advertising is pretty much a given -- we're all desensitized by it to the point that it is hardly noticeable. The other night however, something different caught my ear, an advertisement by Blue Cross Blue Shield of North Carolina. It goes beyond misleading and tells an outright lie.

Before I get ahead of myself, here is a transcript of the commercial.  The image above is of the number in question. The bolded text is the sentence in question.

Think you can't afford health insurance? Let's run the numbers.

[Screen shows $7,026]

Woah! That's how much each American is likely to spend on health care this year. So how can you afford not to have reliable health coverage.

Blue Cross and Blue Shield of North Carolina offers a full range of plans for as little as $113 per month. You get coverage for all this and more. Plus a large provider network. Log on and let us run the numbers for you.

For a free rate quote, log on today.

At first this might seem a bit like a classic misleading technique where a mean value is used with weasel words like "typical" or "average", when it would probably be more appropriate to use a median instead. In this case, because of the wording in the commercial, it's much worse. It's an outright lie. Let's break it down:

The Number: $7,026

The number they are quoting in the commercial is from the CDC as they cite. It is the per-capita health care spending in 2006. It's a bit odd that they would use a number that is so old when newer ones would be potentially more convincing, but my problem doesn't lie with the number itself.

Per-Capita Spending

The key issue is that they are presenting an average, per-capita health care spending, as likely. At best, this is sometimes the case. In the case of health care, it is NOT the case. The average amount of health care spending is HIGHER than the median amount of health care spending. To put this differently, UNC's Geography Department graduates earn more than any other department because Michael Jordan was a Geography major. Healthcare is similar: large outliers pull up the average.

The Lie

According to government statistics this is true:

$7,026. Each American is likely to spend less than this on health care this year.

According to Blue Cross and Blue Shield of North Carolina, this is true:

$7,026. That's how much each American is likely to spend on health care this year.

Can these both be true!? I certainly don't think so. Portraying an average as typical is one thing, but this is an outright lie. Why is this ok?

Wally at the lake

Greeked Style Guide

Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Vestibulum tortor quam, feugiat vitae, ultricies eget, tempor sit amet, ante. Donec eu libero sit amet quam egestas semper. Aenean ultricies mi vitae est. Mauris placerat eleifend leo. Quisque sit amet est et sapien ullamcorper pharetra. Vestibulum erat wisi, condimentum sed, commodo vitae, ornare sit amet, wisi. Aenean fermentum, elit eget tincidunt condimentum, eros ipsum rutrum orci, sagittis tempus lacus enim ac dui. Donec non enim in turpis pulvinar facilisis. Ut felis. Praesent dapibus, neque id cursus faucibus, tortor neque egestas augue, eu vulputate magna eros eu erat. Aliquam erat volutpat. Nam dui mi, tincidunt quis, accumsan porttitor, facilisis luctus, metus.

Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Vestibulum tortor quam, feugiat vitae, ultricies eget, tempor sit amet, ante. Donec eu libero sit amet quam egestas semper. Aenean ultricies mi vitae est. Mauris placerat eleifend leo. Quisque sit amet est et sapien ullamcorper pharetra. Vestibulum erat wisi, condimentum sed, commodo vitae, ornare sit amet, wisi. Aenean fermentum, elit eget tincidunt condimentum, eros ipsum rutrum orci, sagittis tempus lacus enim ac dui. Donec non enim in turpis pulvinar facilisis. Ut felis.

Header Level 2

  1. Lorem ipsum dolor sit amet, consectetuer adipiscing elit.
  2. Aliquam tincidunt mauris eu risus.

Blockquote p.Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vivamus magna. Cras in mi at felis aliquet congue. Ut a est eget ligula molestie gravida. Curabitur massa. Donec eleifend, libero at sagittis mollis, tellus est malesuada tellus, at luctus turpis elit sit amet quam. Vivamus pretium ornare est.

Header Level 3

Header Level 4

		/************************************
		 * Actual syntax highlighter colors.
		 ************************************/
		#header h1 a { 
			display: block; 
			width: 300px; 
			height: 80px; 
		}
		
Header Level 5

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vivamus magna. Cras in mi at felis aliquet congue. Ut a est eget ligula molestie gravida. Curabitur massa. Donec eleifend, libero at sagittis mollis, tellus est malesuada tellus, at luctus turpis elit sit amet quam. Vivamus pretium ornare est.

Horrible Gmail Virus

I think gmail has been infected with a horrible virus.  It causes the interface to become useless for at least 30 seconds to a minute.  Basically, this is what happens:

  1. I open an email with a zip file as an attachment.
  2. I scroll down to download that attachment
  3. I cannot.  It says 'Scanning for viruses...'

At this point I can't download the file I want for as long as a minute sometimes!

For this to be acceptable, the viruses that are going around in these zip files must be terrible.  They must do things far more inconvenient than making me wait a minute to download a file I want.  They must also be capable of changing forms while still in a zip, because gmail runs its virus scan every time I go to get the same attachment.  Obviously once isn't enough.

VotetheSite.com

I've been working with the guys at NMC to create a cool app just in time for the election.  It ishttp://votethesite.com and it lets you browse through congressional races and compare candidates websites.

Check it out and be sure to vote in the election.

 

The Wufoos Rock

I just got a personalized letter last week from Wufoo since I have been a longtime customer.  I wrote a quick post about it and uploaded photos on the New Media Campaigns Web Design Blog .

Investing Online During a Recession

My business partner at New Media Campaigns put up a great post today about the value of investing in marketing during a recession.  (Particularly online).  Read it here:http://www.newmediacampaigns.com/page/tough-times-squeezing-your-marketing-budget-invest-online