Join our HiFi mailing list to receive the latest news & updates

How to Use JSON APIs with jQuery

8 Comment(s) | Posted | by Joel Sutherland | |

One of the best features of jQuery is its simple AJAX functionality. This allows you to easily pull data from other sites and services onto your own site. Learning how to use this functionality makes it easy to integrate any number of services into your websites, making them richer and more interesting to your visitors. It will also make you less dependent on the widgets that companies provide, allowing you to create your own.

jQuery JSON APIFor this post, I am going to show how I created URL Tweet Compete, a tool that allows you to enter multiple urls into a textarea, and it then returns the number of tweets that the they have on Twitter. Be sure to try it out so that you can understand what this post is all about.

The tools uses the Topsy Otter API. This is a fun API to play around with because it is easy to understand and it doesn't require any authentication.  Additionally, it supports jsonp which is important as I will explain later.

The core call in jQuery for this project looks like this:

$.ajax({
    url: "http://otter.topsy.com/urlinfo.js?url=http://www.nytimes.com",
    dataType: 'jsonp',
    success: function(results){
        console.log(results);
    }
});

Now lets get in to the mechanics of how this works.

What are APIs? What is AJAX?

This might be old news, but it's worth covering quickly. You could read all day about APIs and AJAX, but they are also easy enough to understand in concept.

An API is a tool that makes information available to progams in a more convenient format.  As an example, humans can go to Twitter's website in their browser to see a pretty display of tweets.  The Twitter API however presents the tweets in a way that is convenient for programs.  It just gives the info.

AJAX is a phrase that roughly means "fetching information on a loaded page using Javascript".  It is an acronym with a specific meaning, but it is now used more generally.  The "X", for example, stands for XML, but now AJAX is used whenever there is any kind of dynamic content is being displayed, including JSON. Typically, AJAX is used in conjunction with an API.

So how does it work?

In the example above we are initializing an AJAX request to the Topsy API. You can see exactly what happens by checking out the URL yourself, directly: http://otter.topsy.com/urlinfo.js?url=http://www.nytimes.com As you can see, the following is shown:

ajax response

So when that request is made, some data is sent back. We're now able to use this data however we like on the page.  In the case of the URL Tweet Compete app, we're displaying the "trackback_total" value which represents the total number of tweets that have been received.

What is JSONP?

When making AJAX requests to external domains, there are a number of restrictions that apply for security reasons. JSONP is a technique to get around these restrictions. jQuery builds it into their $.ajax() method to make it easy to use.

Whenever you're using an API that is hosted on another domain, you'll need to make sure you're using the jsonp version of the API. Topsy offers an XML, JSON and JSONP version. A common mistake is attempting to use the JSON version which is impossible with javascript on another domain.

With Topsy (and many other APIs), you can select which version you want by changing the extension on your request.  For the XML version, use ".xml", for the JSON version use ".json".  Usually to get the jsonp version, you'll use either ".jsonp" or ".js".

Putting it All Together

So in order to request information from the Topsy API and display it on a page, you'll need some code like this:

$.ajax({
    url: "http://otter.topsy.com/urlinfo.js?url=http://www.nytimes.com",
    dataType: 'jsonp',
    success: function(results){
        var title = results.response.oneforty;
        var numTweets = results.response.trackback_total;
        $('#results').append(title + ' has ' + numTweets + ' tweets.');
    }
});

This code goes and fetches information about the url: http://www.nytimes.com and then displays the number of tweets it has.  Notice that we're doing the displaying within the 'success' function.  This is because we don't get the information back from our Topysy AJAX request immediately.

Instead, once it comes back, jQuery calls the success function that we define and passes in the results so that we can use them.

Hopefully this post is helpful for those new to using APIs and AJAX.  If there are any questions or comments, please leave them below!

A jQuery Flickr Feed Plugin

100 Comment(s) | Posted | by Joel Sutherland | |

View the Demo | Download the Zip

We often work with clients that maintain accounts with Twitter, Flickr, Youtube and other services in addition to their website. Often they will want to pull in data from one of their accounts to their website.  With Flickr, this is pretty easy because they make a simple API available.  Having worked with it a few times, we decided to make it even easier to pull photos from a public feed.

flickr dogs

There are a few examples of this in use on the demo page.  All of the photos on this page have been used with the generous permission of John Roberts (@jroberts13).

Plugin Overview

This plugin works by pulling a JSON feed from Flickr and applying the data it gets back to a template.  For example, we can generate this list of pictures:

<ul>
	<li><img alt="Photo Title" src="http://farm4.static.flickr.com..." /></li>
	<li><img alt="Second Photo Title" src="http://farm4.static.flickr.com..." /></li>
</ul>

From the following jQuery:

$('ul').jflickrfeed({
	limit: 2,
	qstrings: {
		id: '44802888@N04'
	},
	itemTemplate: '<li><img alt="{{title}}" src="{{image_s}}" /></li>'
});

The plugin gets the feed from Flickr using AJAX and applies each image it gets back to the provided template.

The Plugin Options

There are a number of options available on the plugin, these are the defaults:

flickrbase: 'http://api.flickr.com/services/feeds/',
feedapi: 'photos_public.gne',
limit: 20,
qstrings: {
	lang: 'en-us',
	format: 'json',
	jsoncallback: '?'
},
cleanDescription: true,
useTemplate: true,
itemTemplate: '',
itemCallback: function(){}

Here is a description of each one:

  • flickrbase: This is unlikely to be needed.  It is used to set up the url the jQuery AJAX call will need to be made to.
  • feedapi: There are a number of feeds that flickr makes available.  The default is the public feed.  Here is the list of all that are available: http://www.flickr.com/services/feeds/. This has only been tested on feeds that return photos.  So, for example, don't expect good results using this plugin on the Forum discussion feeds.
  • limit: Set how many items you want to loop through.  Flickr seems to limit its feeds to 20, so that is the default.
  • qstrings: This is the most important setting. This is used to request the correct feed.  In my examples I use this to set the user id.  These are automatically added to the request url. Depending on which feed you use (http://www.flickr.com/services/feeds/) there are different sets of query parameters available: http://www.flickr.com/services/feeds/.
  • cleanDescription: Flickr puts all kinds of junk in the description it returns. By default this plugin is set to remove everything but the plain photo description.
  • useTemplate: Set this to false if you don't want to use the plugins templating system.
  • itemTemplate: The template rules are described below.
  • itemCallback: You can add a callback on each item.  The scope is set to the container and the item object is made available.

Typically, the only things that will need to be set are limit, qstrings.id and itemTemplate.

Using the Templates

In order to make it really easy to use any kind of markup needed with this plugin, a simple templating system has been build in.  Here is an example of a template:

<li>
	<a href="{{image_b}}"><img src="{{image_s}}" alt="{{title}}" /></a>
</li>

You can see that this is just basic html with a few special tags mixed in.  All of the tags are surrouned by double curly braces. The plugin works by putting in the correct information for each tag and each item into the template.

The tags that are available depend on what flickr returns for each item.  For the Public Photos API these are: title, link, date_taken, description, published, author, author_id, tags, and image.  For the image property, the plugin uses the Flickr URL scheme to make several sizes available.  You can read about this at http://www.flickr.com/services/api/misc.urls.html.  The image tags available are: image_s, image_t, image_m, image, image_b.

The Callback Parameter and Integration

The plugin's second parameter is a callback.  This has the scope of the containing element and has the entire data response available. This is a great feature if you want to integrate this plugin with others.  Let's say you want to integrate it with colorbox. If you call $('selector').colorbox() and then this plugin it won't work.  This is becuase the plugin is adding elements to the page after the colorbox call.  This is even true if you call colorbox after this plugin.  Since this uses ajax, your images won't be added to the page until well after most of your javascript has run.  (In computer time).

Instead, the trick is to use the callback function.  This allows you to pass in code that you want to run after the images have loaded.  So for example, you can do this:

$('#cbox').jflickrfeed({
	limit: 14,
	qstrings: {
		id: '37304598@N02'
	},
	itemTemplate: '...example...'
}, function(data) {
	$('#cbox a').colorbox();
});
			

Now the colorbox call won't be made on the photos until they are loaded.

Demo and Download

You can see a demo of this plugin on the demo page.  Additionally you can download a zip of this plugin and the example.

As always, if you have any questions or comments, leave them below.  Enjoy!

AutoSprites - A jQuery Menu Plugin

46 Comment(s) | Posted | by Joel Sutherland | |

Update 1/22/2009 - This plugin now contains support for an active state. It is just as easy to use and all of the animation still works with it. Read below to see how it works. (This was originally posted 10/28/2009)

AutoSprites jQuery Menu Plugin

Download the Files (Zip) | View a Demo

We have written and released a jquery dropdown menu plugin as well as a CSS Sprites2 Plugin -- this post is along the same lines. Its purpose is to allow you to build an image-based menu with animated hover states as easily as possible and by using the most concise descriptions possible. To see the results on both a horizontal and vertical menu, check out the demo.

Setting up the jQuery Menu Plugin

The first component when doing something with sprites is a combined image that contains all menu states. For the menu above, this is the image below was used. (This was designed by Liaison Design Group, one of our Partners)

sprites

The image contains, the normal state, the hover state and the active state. The value to doing things this way is that it allows your site to load faster. Rather than downloading an image for each nav item its hover state and its active state, only a single image needs to be downloaded. This minimizes the overhead of many http requests.

The next thing to do, is set up the HTML for the nav bar:


Then we need to set up the CSS. There are a couple of things to note here. We are applying the background image to the containing element so that we don't need to respecify background positioning. This also makes the menu usable if javascript is disabled. Each element needs to have its size defined specifically as well.

#hnav { position: absolute; top: 0; left: 0; width: 615px; height: 72px; background: url('horiz_sprites.gif') no-repeat; }
#hnav li { position: absolute; left: 0; height: 72px; }
	#hnav #hnavhome { width: 82px; left: 0px; }
	#hnav #hnavlocal { width: 146px; left: 82px; }
	#hnav #hnavhigher{ width: 162px; left: 228px; }
	#hnav #hnavcomm { width: 143px; left: 390px; }
	#hnav #hnavnews { width: 82px; left: 533px; }
#hnav li a { display: block; position: absolute; top: 0; left: 0; width: 100%; height: 72px; text-indent: -9999em; }

Notice how much less complicated the CSS is than what is typical with sprites. There is no need to define background positioning for each element and its hover state. The last piece you'll need to do is enable the autosprites plugin:

$(document).ready(function(){
	$('#hnav').autosprites();
});

There are no required options. The plugin defaults to a horizontal menu and fading for the animation. It infers everything else from the CSS. If you would like to customize things, here are the options that are available:

settings = $.extend({
	offset: '100%',
	orientation: 'horizontal',
	over: { opacity: 'show' },
	overSpeed: 500,
	out: { opacity: 'hide' },
	outSpeed: 500,
	activeState: false,
	activeClass: 'active',
	activeSprites: false
}, settings);

The only bit worth explaining is the active state. In the image above, I show three states. By default, you only need two, a normal state and a hover state. If you set 'activeState' to true, it will use the hover state by default. If you want to specify your own active state, simply set 'activeSprites' to true as well.

So that's it! You can specify the minimum amount of information about your menu and the sprites will be built automatically. Be sure to check out the demo and download the zip for your own projects. As always leave a comment if you have any complements, insults, suggestions or questions.

A Special Note on Compiling Javascript

The purpose of using sprites is to minimize HTTP requests. It would be foolish to use this plugin by including jQuery, the minimized plugin, and a setup script. Instead, it is best practice on a production site to bring all of your scripts together into one file, just as sprites bring your images into one file.

Tutorial: A Horizontal jQuery Accordion using Custom Event Binding

20 Comment(s) | Posted | by Joel Sutherland | |

This is the second of two posts about a site we recently launched for a non-profit called Striving for More. This is a great new organization that has started with the goal of improving overall care for young cancer patients. It was a fun and deserving project with a great design:

Striving for More

The first post was about how to build a custom jQuery Slideshow on top of some popular jQuery plugins. It covered the required html, css and js needed and it also gave a look into the through process that went into it. This post will take the same approach, but instead look at the custom jQuery horizontal accordion that is on the homepage. Unlike the last project, this one will be build without the help of any plugins. It was created entirely from scratch using jQuery custom events.

Here is a look at the final product.

Horizontal jQuery Accordion

What is it?

Essentially, this is a horizontal accordion that also changes the text below it on each transition. The one difference between this and a traditional accordion is that when a slide becomes active or inactive, it doesn't just shrink. Instead it slides behind the other slides. Click around on it above to see what I mean.

The HTML

The html for this project is really straightforward. There is a group of slides and a group of content:

<div id="slideshow">
	<ol id="slides">
		<li class="slide open" id="slide-[SLIDE NUMBER]">
			<a href="[SLIDE LINK]">
				<img src="[SLIDE IMAGE]" alt="" />
			</a>
			<a class="slidebutton" href="javascript:void(0);"><img src="[SLIDE BUTTON]" alt="" /></a>
		</li>
		...
	</ol>
	<ol id="slidecontents">
		<li class="slidecontent" id="content-slide-[SLIDE NUMBER]">
			[SLIDE CONTENT]
		</li>
		...
	</ol>
</div>

The html is in two logical groups, the slide images/navigation and the slide content. These are paired by convention using programatic id attributes. Notice that each of the image slides and the content slides has an id with the [SLIDE NUMBER] in it. This makes the javascript much simpler.

Ideally the content would be grouped in with the images. This would have made for better markup, as the related items would be put together. This would have required a lot of css positioning trickery since the content wasn't supposed to move with the slide. For the sake of overall simplicity, some html complexity was added.

The last thing worth noting here is that the slide button text is actually a rendered image. That text can't be rotated reliably in all browsers is really sad. I am confident that this will be accomplished shortly with Canvas. If you're wondering which browsers are the offenders here, you'll probably be surprised. Text can be rotated reliably in EVERY major browser except for Firefox 2.0. It even works in IE. Alas.

The CSS

The CSS for this project is probably the simplest part. You'll only notice one little quirk:

#slides { position: absolute; top: 21px; left: 22px; width: 577px; height: 285px; overflow: hidden; }
#slides .slide { position: absolute; top: 0px; width: 541px; }
#slides .slide img { position: absolute; top: 0px; left: 0px; }
#slides .slide .slidebutton { display: block; position: absolute; top: 0px; right: 0px; height: 285px; width: 21px; background: #693d5e; text-decoration: none; border-right: 1px solid white; }
#slides .active .slidebutton { background: #55354a; }
#slides .slide .slidebutton img { position: absolute; top: auto; display: block; bottom: 5px; left: 5px; }
/* Manually place slides to begin */
#slide-1 { position: absolute; top: 0; right: 44px; z-index: 3; }
#slide-2 { position: absolute; top: 0; right: 22px; z-index: 2; }
#slide-3 { position: absolute; top: 0; right: 0px; z-index: 1; }

It's all straighforward except for that bit at the bottom. I've hardcoded the number of slides. This is typically something I like to avoid, but there were a couple of reasons for it on this project:

  1. I was assured that these slides would be unchanged for quite some time.
  2. At least some CSS Positioning would be required so the page wouldn't look broken while the JS loaded. By being exact there would be no jarring readjustment at all.
  3. It was easier.

These reasons made the decision obvious. As a quick aside and bonus, here is the css that could be used to rotate the text in CSS. Note that this depends on slightly different markup and it just won't work in Firefox 2.0. So remeber that until FFox2.0 disappears this is useless, though fascinating.

#slides .slide .slidebutton span 
{ display: block; text-align: right; -webkit-transform: rotate(90deg);  -moz-transform: rotate(90deg);
						position: absolute; bottom: 100px; left: -90px; width: 200px;
						color: #f2ecd0; font-family: verdana, sans-serif; font-size: 12px; }
/* Put the following in your IE stylesheet */
#slides .slide .slidebutton span { bottom: 190px; left:2px; filter: progid:DXImageTransform.Microsoft.BasicImage(rotation=1); }

The jQuery

The jQuery for this little project was the most fun. It ended up being very compact due to the intial positioning of the slides using CSS and because I used custom events.

What are custom events? In short, they are functions that you can bind to jQuery selectors. This lets you associate actions with the objects that do them, rather than with what triggers them. As an example, you could bind the event 'toggle' to a lightbulb and then trigger it from any number of switches. So if you have multiple switches, they all don't need to keep track of the lightbulb's state. They can just call toggle and the bulb will handle it. (If you like this example, don't credit me. It's borrowed from a great article on jQuery Custom Events written by Rebecca Murphey).

So here is the entirety of the jQuery code:

/* Binding Events to the slides */
$('.slide')
	.bind('open', function(){
		if(! $(this).hasClass('open')){
			$(this).next().trigger('open');
			$(this).addClass('open');
			$(this).animate({right: "-=511px"});
		}
		else{
			$(this).prev().trigger('close');
		}
		$(this).siblings().removeClass('active');
		$(this).addClass('active');
	})
	.bind('close', function(){
		if($(this).hasClass('open')){
			$(this).removeClass('open');
			$(this).animate({right: "+=511px"});
			$(this).prev().trigger('close');
		}
	});
		
/* Binding Events to the Slide Contents */
$('.slidecontent').bind('show', function(){
	$('.slidecontent').removeClass('open');
	$(this).addClass('open');
});

/* Triggering from the buttons */
$('.slidebutton').click(function(){
	$(this).parent().trigger('open');
	$('#content-' + $(this).parent().attr('id')).trigger('show');
});

This is certainly terse, so it is worth explaining. I'll start with the events we are binding to '.slide', open and close. To set the stage, remember that each slide is either open (navigation on the right), or closed (navigation on the left). I am keeping track of this by applying an 'open' or 'closed' class to each slide. This is a fairly standard technique.

Where things might get a bit tricky lie within how an accordion works. The visibile slide isn't the only slide that is open. The slides that come after it must be open as well (their navigation is on the right). So when the second slide is active, the first must be closed and the second and third must be open. This problem gets handled with a little big of recursion.

The Event Binding

Let's look at the close event, as it is the simpler of the two. When we close a slide, we first check that it is open. If it is closed, there is nothing to do. If it is open, we close it and then close the slide immediately to its left. This repeats until there isn't a slide to the left or it reaches a slide that has already been closed.

The open event is only a little more complicated. It works in the exact same way as the close event, except trickles to the right. It also updates which slide is active at each stop along the way.

Finally you can see how the 'show' event is bound to the slide contents. All this does is remove an open class from every slide content, and then add it back to the one that has been triggered.

As you can see, a lot of complexity has been encapsulated under these events. This makes it really easy to jump to a particular slide. All that needs to happen is to trigger the 'open' event on the desired slide and the 'show' event on the correct content. This is exactly what the '.slidebutton' code does.

Putting it all together

With all of the pieces in place you can see it in action below. Be sure to leave any questions or comments you have about this in our comments below.

jQuery Horizontal Accordion

Tutorial: A jQuery Slideshow for a Good Cause

6 Comment(s) | Posted | by Joel Sutherland | |

We recently launched a site for a new non-profit called Striving for More. The project was a lot of fun. The site is great-looking, has some cool features, and more importantly it was for a good cause.

In this post, I am going to cover one of the more important features of the site: an interactive gallery that tells Colleen's Story. I'll breakdown how it was built and the reasons for doing some of the things the way I did. It ends up being very simple and a great example of the power that can be had by combining and tweaking jQuery plugins.

Here is the final product so you can see where this is headed:

What is it?

Colleen's Story is a simple slideshow that can be navigated in any order with an introduction screen. Each slide has a nice navigation button, some narrative and a cool graphic. Because we didn't want the navigation to move around, the content needed to scroll in place, another requirement. For something that looked this good, overflow: auto; wouldn't cut it. After doing some looking around, I decided to use the following plugins for the project:

  • Cycle - This is one of my favorite plugins. If you haven't checked it out you need to. With some improvments that have come in the last 6 months or so it is the only plugin you'll ever need for rotating content. We've rolled our own cycle-like jquery code in the past, but that is rarely necessary. On this project, Cycle will handle all of the slide transitions as well as the navigation.
  • jScrollPane - I'm not generally a fan of replacing the default behavior of browsers, but this situation required it. I played around with serveral plugins before settling on this one which seems to have the fewest downsides.

The HTML

To use these plugins will require that we structure our html in a certain way. Here is how it is setup:

<div id="gallery">
	<div id="gallery-intro">
		[Introduction Content]
		<a href="javascript:void(0);" id="startslides">Begin</a>
	</div>
	<div id="gallery-slides" class="hidden">
		<ol>
			<li id="slide-[slidenum]">
				<div class="slide-content">
					<h2>[Slide Title]</h2>
					<div class="scroll-content">
					[Slide Content]
					</div>
				</div>
				<img class="slide-image" src="[Slide Image]" alt="" />
			</li>
			...
		</ol>
	</div><!-- gallery-slides -->
	<div id="gallery-nav">
		<ol>
			<li id="slide-1-nav">1. Monkey</li>
			<li id="slide-2-nav">2. Necklace</li>
			<li id="slide-3-nav">3. IV Beads</li>
			<li id="slide-4-nav">4. Bag</li>
			<li id="slide-5-nav">5. Blistex</li>
			<li id="slide-6-nav">6. Notebook</li>
			<li id="slide-7-nav">7. Pink Hair</li>
		</ol>
	</div><!-- gallery-nav -->
</div><!-- gallery -->

There are some things to point out here:

  • The Gallery Intro

    Before the slideshow is shown, a description of its purpose is shown. This is grouped independently of the slides. The plan is to make this disappear once the slideshow is started.

  • The group of slides

    All Cycle asks for is a group of slides that are children to one element. In this case it is the ol. We'll end up calling cycle on "#gallery-slides ol". Also notice that I have given this the class "hidden". I do this so that I can hide the slides with css rather than javascript. This is important to do, otherwise while the page loads they will flash.

  • The Navigation

    Cycle provides a navigation (pager) generator. For this project I wanted to have all of my html in one place and give good text descriptions for each slide. Having this dynamicly match the number of slides didn't matter either because these were set in stone. Instead, I just used an id attribute convetion so I could write some simple javascript to link the navigation to the slides.

  • Scroll-Content Class

    I wrapped the content of each slide in a container with the class "scroll-content". This is so that we can target it if necessary using the jScrollPane plugin.

The CSS

A concern with this site due to the texture used was download size. While the end result is not perfect, it was taken into consideration when putting this together. The overall strategy was to use one background image for the slideshow frame and let the slide text, images and navigation float over it. One concession was to also include some of the background in the slide images. While this made for some redundant information, the use of jpg compression instead of a 24-bit or even 8-bit png more than made up for it. Finally, sprites were used for the navigation.

Here is the major layout css:

/* Container */
#gallery { position: relative; width: 696px; height: 494px; background: url('gallery-background.jpg'); }

/* Intro Container */
#gallery-intro { position: absolute; top: 8px; left: 9px; height: 268px; width: 459px; padding: 70px 110px;
				font: italic 16px Georgia,serif; color: #1e5584; line-height: 32px; text-align: center; }
#gallery-intro strong { color: #bc9906; display: block; font-weight: normal; }
#startslides { width: 116px; height: 30px; display: block; margin: 20px auto; background: url('gallery-begin.jpg'); text-indent: -9999em; }

/* Slides */
#gallery-slides { position: absolute; top: 8px; left: 9px; height: 408px; width: 679px; overflow: hidden; background: transparent; }
#gallery-slides ol { position: absolute; top: 0; left: 0; list-style: none; margin: 0; padding: 0; width: 679px; height: 408px; background: transparent; }
#gallery-slides ol li { width: 629px; height: 338px; padding: 25px; }

/* Slide Components */
#gallery-slides .slide-content { width: 340px; padding-right: 20px; height: 338px; line-height: 18px; z-index: 2; }
#gallery-slides .scroll-content { overflow: auto; width: 320px; padding-right: 20px; height: 315px; }
#gallery-slides .slide-content p { margin: 6px 0; }
#gallery-slides .slide-content h2 { margin: 0px 0 6px 0; font: italic 25px Georgia,serif; color: #bc9906;  }
#gallery-slides .slide-image { position: absolute; bottom: -25px; right: 1px; z-index: 1; }

The quick things to notice are:

  • The container is positioned relative so that everything else can be placed absolute inside of it.
  • ".scroll-content" has overflow set to auto. This is required for the jScrollPane plugin.

The navigation was also positioned absolute and set up with a basic CSS sprites technique. You can see the image used here. I am using '.on' in addition to the ':hover' pseudo-class so that we can get the hover states to work in IE6 using javascript. You can get more information on this technique in detail in a classic article on A List Apart. For those of you interested in using the technique for navigation menus, I've also written a plugin to make that dead simple called jQuery AutoSprites.

#gallery-nav { position: absolute; top: 425px; left: 8px; width: 680px; height: 50px; }
#gallery-nav ol { position: absolute; margin: 0; padding: 0; top: 0; left: 0; width: 680px; height: 50px; background: url('gallery-sprites.jpg'); }
#gallery-nav ol li { list-style: none; margin: 0; padding: 0; position: absolute; top: 0; left: 100px; width: 85px; height: 50px; text-indent: -9999em; cursor: pointer; cursor: hand; }
#gallery-nav ol li.activeslide, #gallery-nav ol li.hov { background-image: url('images/gallery-sprites.jpg'); }
	#gallery-nav #slide-1-nav { left: 0px; width: 100px; }
	#gallery-nav #slide-1-nav.activeslide, #gallery-nav #slide-1-nav.hov{ background-position: 0px -50px; }
	#gallery-nav #slide-2-nav { left: 97px; width: 100px; }
	#gallery-nav #slide-2-nav.activeslide, #gallery-nav #slide-2-nav.hov { background-position: -97px -50px; }
	#gallery-nav #slide-3-nav { left: 194px; width: 100px; }
	#gallery-nav #slide-3-nav.activeslide, #gallery-nav #slide-3-nav.hov { background-position: -194px -50px; }
	#gallery-nav #slide-4-nav { left: 291px; width: 100px; }
	#gallery-nav #slide-4-nav.activeslide, #gallery-nav #slide-4-nav.hov { background-position: -291px -50px; }
	#gallery-nav #slide-5-nav { left: 388px; width: 100px; }
	#gallery-nav #slide-5-nav.activeslide, #gallery-nav #slide-5-nav.hov{ background-position: -388px -50px; }
	#gallery-nav #slide-6-nav { left: 485px; width: 100px; }
	#gallery-nav #slide-6-nav.activeslide, #gallery-nav #slide-6-nav.hov { background-position: -485px -50px; }
	#gallery-nav #slide-7-nav { left: 582px; width: 100px; }
	#gallery-nav #slide-7-nav.activeslide, #gallery-nav #slide-7-nav.hov { background-position: -582px -50px; }

The Javascript

Since our plugins come with quite a bit out of the box it is really simple to get the jQuery running. The first step was to handle the items hidden by css I described above. We can do this right away since the javascript will execute quickly once it gets going as it will be replaced bya jQuery hide.

$('.hidden').removeClass('hidden');
$('#gallery-slides').hide();

Next I got the navigation hover states working in IE6 which needs javascript since it doesn't recognize the :hover psuedo-class on non-anchor elements.

$('#gallery-nav ol li').hover(
	function(){ $(this).addClass('hov'); },
	function(){ $(this).removeClass('hov'); }
);

Next was the simple step of enabling jScrollPane. Don't forget to set these containers as overflow:auto in the css too.

$('#gallery-slides .scroll-content').jScrollPane({
	scrollbarWidth: '10'
});

Setting up a jQuery Cycle is easy, but there was a trick needed for IE. Because I used the fade effect, Cycle sets a background color during the transition to get the text fading to work correctly. I reset this to transparent once the transition is over using the after callback. While this may seem like a pain, little features like this are part of the reason to use established plugins over something homegrown.

$('#gallery-slides ol').cycle({
	timeout: 0,
	fx: 'fade',
	after: function(){
		$('#gallery-slides ol li').css('background', 'transparent');
	}
});

The last step is adding the custom navigation features. You'll notice that the id of the nav item is used to figure out which slide to show. I also set up the swap between the intro and the slides to occur if either the navigation or "Begin" button is pressed.

$('#gallery-nav ol li').click(function(){
	$('#gallery-slides').fadeIn();
	$('#gallery-intro').fadeOut();
	$(this).parent().children().removeClass('activeslide');
	$(this).addClass('activeslide');
	var slidenum = Number($(this).attr('id').substr(6,1)) - 1;
	$('#gallery-slides ol').cycle(slidenum);	
});
$('#startslides').click(function(){
	$('#gallery-slides').fadeIn();
	$('#gallery-intro').fadeOut();
	$('#slide-1-nav').trigger('click');
});

Conclusion

So that's it. Once again you can check out the final product on the Striving for More site. Next week I'll post a tutorial about how the homepage slider was done entirely from scractch. If you want to read about that when it comes out, you should subscribe to the blog.

Use HTML5 form attributes now with nmcFormHelper plugin for jQuery

12 Comment(s) | Posted | by Eli Van Zoeren | |

Inayaili de León's post last week on 24 ways reminded me about some of the new attributes that HTML5 will be adding to the <input> element. In addition to the flashy new input types (search, color, date, etc.), there are several more mundane, but just as useful, new attributes that can be used on the input types we already have. I created a small jQuery plugin that checks if these attributes are supported natively, and if not it adds support via JavaScript. See an example, or continue reading for the full explanation.

Placeholder

A common trick is to set the value of a text input to a short hint about the type of information that should be entered there. Then a couple lines of JavaScript are used to clear that value when the user clicks or tabs into the input. Although there are usability issues with this technique, its convenience is hard to resist. The HTML5 spec includes a new placeholder attribute that creates the same effect without the usability problems.

To Use:

<input type="text" name="name" id="name" placeholder="Enter your first and last names" />

Autofocus

When the primary purpose of a page is the form—a login page, for instance—it is helpful to start out with the focus on the first input, so the user can just start typing. You can use the new autofocus attribute on the first element to do that. (Be careful, though: setting autofocus on a non-essential form, like a comment form, can be very annoying.)

To Use:

<input type="text" name="name" id="name" autofocus="autofocus" />

Required

Setting the required attribute prevents the form from submitting unless the input has some value.

To Use:

<input type="text" name="name" id="name" required="required" title="This is required" />

Pattern

The pattern attribute lets you set a regular expression pattern that must be matched by the input value before the form can be submitted. This is a very powerful tool, allowing for complex validations. Our HiFi RexExp Tool will help you create regular expressions that test for anything from credit card numbers to urls. You should also read the HTML5 spec on the topic, as there are a few caveats. In particular, be aware that the pattern matches the entire value by default, and you should not wrap the expression in forward slashes.

To Use:

<!-- Only accept US zip codes -->
<input type="text" name="zip" id="zip" pattern="(^d{5}$)|(^d{5}-d{4}$)" title="US zip codes only" />

Using the Plugin

Some or all of these new attributes are supported by both Safari and Opera. But Firefox and Internet Explorer do not support them natively at this time. To be safe, the nmcFormHelper plugin checks for availability of each attribute (using a technique suggested by Mark Pilgrim) and, if it doesn't exist, uses JavaScript to emulate support.

At a minumum, you just need to include my script and place a single line in your $(document).ready() block: nmcFormHelper.init();. That will set up all of the new attributes, and you're ready to go.

Options

  • Placeholder styling: The placeholders are styled to match the native placeholder functionality in Safari. If you wish to set a different style, you can set nmcFormHelper.placeholder.styling = {'color':'red','font-style':'italic'}; or whatever look you choose.
  • Validation functions: The required and pattern attributes will prevent form submission and display an error if the value does not exist or does not match the pattern. By default, a new label will be added after each invalid input, containing the title text of the input. But you can write a function to do anything you want! Just override the functions nmcFormHelper.validation.showErrors and nmcFormHelper.validation.hideErrors (the latter function should undo the former). Both functions will be passed a jQuery object containing all the elements that are affected. Each element will also have one or both of the classes "requiredError" or "patternError" set.

Bonus!

Since Internet Explorer does not support CSS attribute selectors, it can be hard to style a text input, for instance, without screwing up your buttons, or vice-versa. So the plugin also adds a class to each of your inputs containing "input-" and the type of the input (i.e. "input-submit"). That way, you can style them individually.

See an example

Get the Code

Full, commented version

Minified version

Easy drop down menus with nmcDropDown

22 Comment(s) | Posted | by Eli Van Zoeren | |

nmcDropDown in use on ncbowd.comSince I released my nmcDropDown plugin for jQuery two weeks ago, several people have been asking for a simple example of how to use it. Althought the plugin takes care of all the behavior automatically, you still need to style and format the menu using CSS. In this post I will demonstrate two simple menu styles that use nmcDropDown.

The bare minimum

The examples below have styling and effects to make them look nice, but first I will show you the minimum you need to get your menus running. First off, you need a set of nested lists and link to create the structure of your menus:

<ul id="nav">
  <li><a href="#">Item One</a>
    <ul>
      <li><a href="#">Sub-menu Item 1</a></li>
      <li><a href="#">Sub-menu Item 2</a></li>
      <li><a href="#">Sub-menu Item 3</a></li>
    </ul>
  </li>
  <li><a href="#">Item Two</a>
    <ul>
      <li><a href="#">Sub-menu Item 1</a></li>
      <li><a href="#">Sub-menu Item 2</a></li>
      <li><a href="#">Sub-menu Item 3</a></li>
    </ul>
  </li>
  <li><a href="#">Item Three</a>
    <ul>
      <li><a href="#">Sub-menu Item 1</a></li>
      <li><a href="#">Sub-menu Item 2</a></li>
      <li><a href="#">Sub-menu Item 3</a></li>
    </ul>
  </li>
</ul>

Now you need a bit of CSS to put everything in its correct place. This menu isn't going to look nice, but it will give you a starting point from which you can match your site's overall aesthetic.

#nav { float: right; height: 30px; }
#nav li { float: left; position: relative; }
#nav li a { display: block; padding: 5px 10px; line-height: 20px; }
#nav li ul { display: none; position: absolute; top: 30px; left: 0; width: 120px; background: #fff; }
#nav li:hover ul { display: block; }
#nav li ul li { float: none; }
#nav li ul li a { display: inline-block; }
#nav li ul li a { display: block; }

The most important thing here is to set #nav li to position: relative; and #nav li ul to position: absolute; to the submenus are aligned with their parent item. In the interest of accessibility, we are also hiding the submenus in the CSS (#nav li ul { display: none; }) and showing them with their parent li is hovered over (#nav li:hover ul { display: block; }. That way, if JavaScript is disabled, the menus will still work in every browser but Internet Explorer 6. JavaScript is always required for drop-downs to work in IE6, unfortunately. Speaking of which, did you notice the oddity at the end where we declare the links as display: inline-block and then re-declare them at display: block? That is the only concession we need to make to Internet Explorer bugs—it removes the extra space IE6 inserts between list items, as discovered by Roger Johansson.

This CSS will create a horizontal menu with drop-downs, but by changing a few lines, you could just as easily make it a vertical menu with fly-outs.

Finally, the JavaScript to hook up the nmcDropDown script. Make sure you also paste the nmcDropDown script itself (and the HoverIntent plugin, if you wish to use it) into the JavaScript file.

$('#nav').nmcDropDown();

Makin' it Pretty

Screenshot of sample page

Now that we have a functioning menu, we can start styling it. I have created an sample page with two different examples using nmcDropDown.

The first—in the top-right of the page—is based on the simplified example above, just with additional CSS to style the menu bar and drop-downs. I also added an additional parameter to the call in JavaScript to make the menus slide down instead of fading in: $('#nav').nmcDropDown({show: {height: 'show', opacity: 'show'}});.

The second example is a little more interesting, as it's actually not a menu at all. In the right-hand sidebar, I am using nmcDropDown to create an informational panel with four heading that, which clicked on, each reveal a bit of text. To do this, I replaced the second level of <ul>s in my HTML with paragraphs. I then used the following CSS to line arrange everything vertically:

#sidebarNav { padding: 10px 0; background: #ccc; border: 1px solid #bbb; -webkit-border-radius: 4px; -moz-border-radius: 4px; border-radius: 4px; }
#sidebarNav li { border-top: 0 solid #ccc; }
#sidebarNav li:hover, #sidebarNav li.open { background: #bbb; }
#sidebarNav li a { display: block; padding: 5px 10px; line-height: 20px; color: #444; font-weight: bold; text-decoration: none; }
#sidebarNav li p { display: none; padding: 5px 10px 10px; color: #444; border-top: 1px dashed #aaa; }
#sidebarNav li:hover p { display: block; }

Finally, in the JavaScript I told nmcDropDown to activate on click rather than hover and to look for my paragraph instead of the unordered-list it usually expects:

$('#sidebarNav').nmcDropDown({
  trigger: 'click',
  submenu_selector: 'p',
  show: {height: 'show'},
  hide: {height: 'hide'}
});

Please look at the sample page to try these out, and view source to examine the code in more detail. If you find another creative way to use nmcDropDown, please link to it in the comments.

nmcDropDown: A Drop-Down Menu Plugin for jQuery

34 Comment(s) | Posted | by Eli Van Zoeren | |

ncbowd

In my post on using template site to save time, I included a quick jQuery plugin for creating drop-down menus. Although that code has served me well I thought it was time to revisit it and make it more flexible and bullet-proof. This is the updated version that I will be including in my blank site template going forward

I found that I was still having to modify my plugin code to accomodate variations in interaction design. Since I sometimes wanted the menus to only appear whe n the y are clicked—rather than on hover—now that is an option. Also, when the top-level menu items are smaller (or when the sub-menus fly out from the side) the usability can be vastly increased by Brian Cherne's wonderful hoverIntent plugin. HoverIntent keeps the sub-menu from disappearing if your pointer leaves the edge for a split-second. This version will use hoverIntent automatically if you have it; otherwise it will revert to the standard hover event. I recommend copying the minified version of hoverIntent into the bottom of your main JavaScript file. It is quite small and including it in your main file will save an http request and speed up your page loading time.

Usage

You should create your navigation as a nested unordered list. Linking the top-level items is optional and will not change the working of the plugin. You should style your menu first with css. How you do that is up to you, but you should set the sub-menus to display: none (this is actually optional, but will prevent the sub-menus from flashing on page-load).

<ul id="nav">
    <li>About
        <ul>
            <li><a href="#">Profile</a></li>
            <li><a href="#">Board of Directors</a></li>
            <li><a href="#">Contact Info</a></li>
        </ul>
    </li>
    <li><a href="#">Products</a>
        <ul>
            <li><a href="#">Widgets</a></li>
            <li><a href="#">Doohickeys</a></li>
            <li><a href="#">Thing-a-ma-bobs</a></li>
        </ul>
    </li>
</ul>

The nmcDropDown plugin comes with sensible defaults, so you can just call it on the <ul> element that contains your navigation. The plugin will check each menu item to see if it has a sub-menu and set it up as a drop-down if it does.

$('#nav').nmcDropDown();

Configuration

If you want more control over the way your menu works, there are a number of configuration options available to you. Pass an object containing any that you want to change in as the first parameter of the nmcDropDown() call.

$('#nav').nmcDropDown({trigger: 'click'});

Available Options:

  • trigger: Event on which to show or hide the sub-menu, can be 'hover' or 'click'. ('hover')
  • active_class: Class to give open menu items, useful for styling. ('open')
  • submenu_selector: The element immediately below the top-level list-items containing the sub-menu. ('ul')
  • show: Effect(s) to use when showing the sub-menu. ({opacity: 'show'})
  • show_speed: Speed of the show transition. (300)
  • show_delay: Delay before the sub-menu is shown (requires HoverIntent). (50)
  • hide: Effect(s) to use when hiding the sub-menu. ({opacity: 'hide'})
  • hide_speed: Speed of the hide transition. (200)
  • hide_delay: Delay before the sub-menu is hidden (requires HoverIntent). (50)
  • fix_IE: This will attempt to fix IE 6 and 7's problems with z-index, where the sub-menu appears behind the body of the page. Set to false if it is interfering with your other styling. (true)

Example

We recently launched a website for North Carolina Business Opportunity and Workforce Development, a program that helps women, minorities, and small businesses secure NCDOT contracts. I created drop-down menus that use the nmcDropDown plugin with custom show and hide animations for an interesting effect. The show animation is {opacity: 'show', top: '-=10px'} (hide is exactly the reverse), which fades the menu in while sliding it up from below.

Update: I have also created and written up an example of how to use nmcDropDown, including HTML and CSS.

Download

Full, commented version (3.5kb)

Minified version (1.3kb)

jCaption: jQuery Image Captions with Customizable Markup, Style and Animation

75 Comment(s) | Posted | by Joel Sutherland | |

Orginally Posted March 2, 2009 | Last Updated November 4, 2009

jCaption is a jQuery plugin designed to make adding captions to a page dead simple. It takes an image element and uses one of its attributes to build the markup for a caption. It allows for both arbitrary styling and markup.

Demo Image

Dealing with image captions on the web can be a big pain. The code structure for nearly any caption looks something like the following:

<div>
	<img src="image.gif" alt="" />
	<p>Caption Text</p>
</div>

While writing such markup for every image is merely an inconvenience for web developers, it is an impossibility for most of thier clients. Many clients use a web-based WYSIWYG editor to create and edit their pages through a CMS. It would be nearly impossible to expect them to add this markup around their images.

This was a problem I faced when building a site for a client. I found well-concepted solution in Captify, but I found it too restrive for my needs. I proceeded by writing a version that met the following requirements:

  1. Follow jQuery Conventions - Animations shouldn't be handled by passing in a string, instead arbitrary animations should be allowed.
  2. Markup Should be Arbitrary - Other than the tag that is required, other markup should be arbitrary.
  3. Optionally Allow Placement From Text-Editors - Web-Editors like tinyMCE or FCKditor allow users to align images to the left or right of text. Depending on the version, this is accomplished using the "align" attribute or "style" attribute. This plugin accomodates both and makes sure that the caption is correctly placed as well.

Using the plugin

Using the plugin is dead simple. Just use apply the .jcaption() method to the images you want:

$('img').jcaption();

By default this will take the following image:

<img src="image.jpg" alt="Some caption text" />

and produce the following markup:

<div class="caption">
	<img src="image.jpg" alt="Some caption text" />
	<p>Some caption text</p>
</div>

The options will allow you to control the elements and classes that the plugin produces. Additionally, to accomodate text editors, the plugin can copy the styling that was applied to the image to the caption instead, and take the images "align" attribute and append it to the caption class. So for text editors that place images using align="left" you can instead have the plugin add "left" as a class to the caption so that you can place the entire caption using your stylesheet.

Options

$('img').jcaption({
	//Element to wrap the image and caption in
	wrapperElement: 'div',
	
	//Class for wrapper element
	wrapperClass: 'caption',
	
	//Caption Element
	captionElement: 'p',
	
	//Attribute of image to use as caption source
	imageAttr: 'alt',

	//If true, it checks to make sure there is caption copy before running on each image
	requireText: true,
	
	//Should inline style be copied from img element to wrapper
	copyStyle: false,
	
	//Strip inline style from image
	removeStyle: true,
	
	//Strip align attribute from image
	removeAlign: true,
	
	//Assign the value of the image's align attribute as a class to the wrapper
	copyAlignmentToClass: false,

	//Assign the value of the image's float value as a class to the wrapper
	copyFloatToClass: true,

	//Assign a width to the wrapper that matches the image
	autoWidth: true,
	
	//Animate on hover over the image
	animate: false,
	
	//Show Animation
	show: {opacity: 'show'},
	showDuration: 200,
	
	//Hide Animation
	hide: {opacity: 'hide'},
	hideDuration: 200	
});

You'll see that any arbitrary animations are possible by setting up the options in this manner.

Demo

Demo Image

View a Demo of this plugin with and without animations here. The captions on the left are animated and the caption on the right is not.

Download the plugin

This plugin has been tested in IE 6 and 7, Firefox 2 and 3, Safari and Chrome.

Updated Sept. 2, 2009 - Added CopyFloattoClass, improved some documentation and changed defaults to reflect the current state of text editors.

Updated Nov. 4, 2009 - Added requireText, allowing the plugin to be run even if there is no caption text.

Download a zip of the plugin and the sample.

Lazy Development: Using Templates to Save Time

6 Comment(s) | Posted | by Eli Van Zoeren | |

One of my high school teachers always used to tell me that laziness is the mother of invention. Nowhere is this more true than in web and software development. Coders, by nature, are a lazy bunch and are always looking for ways to save time and effort. The Don't Repeat Yourself principal is a prominent expression of this philosophy: the same information should never be repeated more than once in your code.

Even though all of the work we do for our clients is unique and individual, there are many elements that are repeated throughout every project. So it only made sense for me to create a template site folder with everything I need to get started on a new project. This saves me time, which saves our clients money. I am going to describe below what is in my default template. This will almost certainly not be what should be in your default template—that will depend on your personal workflow, CMS, and stylistic preferences—but it should give you some inspiration for things to consider including.

Overview

My template folder contains two sub-folders. Static, which I will discuss in the following sections, contains my default html, css, and javascript files. I code everything to a static templates before putting them on our CMS, since I find it faster and easier to catch problems at that point. I usually create the CMS templates directly on our server, but if you prefer to have a local copy of your CMS, you could include an empty installation of it in another sub-folder here. The other sub-folder I start with is mockups. In there I have the Photoshop template from the 960 Grid System. Although I don't use their css framework, I find having a pre-set grid is helpful whenever I start a new design. Since many of the designs I am coding come from our agency partners, more often than not I just delete that Photoshop template and copy the mockups we've been given into this folder.

HTML

In my static folder, there is one html file: interior.html. I have found that it is almost always better to code an interior page first, and then move on to the homepage. After all, there are many times more interior pages on the average site, and they are where visitors will spend most of their time (hopefully!). Once I have the interior page coded and browser-tested, I duplicate it to index.html and adapt it to the homepage. On more complicated sites there might be more than one interior page design, so I again start with the most generic of them and then duplicate and adapt.

I include plenty of dummy-text in my default iterior.html to give me something to style. Make sure you have a couple of sub-headings, an unordered list, a blockquote…anything that is likely to have individual styles. I also start with a variety of things I might need in the <head> section: potentially useful meta-date (including the viewport meta-tag for the iPhone), conditional comments for IE 6 and 7, a link to the RSS feed, and some default scripts.

My interior.html template

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">

<head>
    <title>Site Title</title>
    <meta http-equiv="content-type" content="text/html; charset=utf-8" />
    <meta name="DC.language" content="en" />
    <meta name="DC.creator" content="{author}" />
    <meta name="DC.publisher" content="New Media Campaigns" />
    <meta name="viewport" content="width={pixel width}" />

    <link rel="alternate" type="application/rss+xml" title="RSS feed" href="" />
    <link rel="shortcut icon" type="image/png" href="{$base_url}images/favicon.png" />

    <link href="css/all.css" rel="stylesheet" type="text/css" media="all" />
    <!--[if IE 7]><link href="css/ie7.css" rel="stylesheet" type="text/css" media="all" /><![endif]-->
    <!--[if IE 6]><link href="css/ie6.css" rel="stylesheet" type="text/css" media="all" /><![endif]-->

    <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.3/jquery.min.js" type="text/javascript"></script>
    <script src="js/site.js" type="text/javascript"></script>
    <!--[if IE 6]><script src="js/DD_belatedPNG.js" type="text/javascript"></script><script type="text/javascript">DD_belatedPNG.fix('');</script><![endif]-->
</head>

<body>
    <div id="wrapper">

        <div id="header">
            <h2 id="logo"><a href="{$base_url}"></a></h2>
            <a href="#content" id="skip">Skip to content...</a>

            <ul id="nav">
                <li><a href="{$base_url}"></a></li>
                <li><a href="{$base_url}"></a></li>
                <li><a href="{$base_url}"></a></li>
            </ul>
        </div>

        <div id="content">
            <h1>Page Title</h1>

            <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Etiam eu metus velit. Sed felis sem, venenatis at ullamcorper a, ornare sit amet nunc. Nunc id massa turpis. In dolor dui, ultricies sit amet mattis vel, cursus non eros. Pellentesque ut mi arcu, ac scelerisque dolor. Phasellus neque nibh, tincidunt quis mattis vel, scelerisque et metus.</p>

            <p>Nullam fermentum pulvinar porta. In hac habitasse platea dictumst. Phasellus non nunc diam, in lacinia dolor. Cras nec eros in metus elementum rhoncus. Phasellus viverra malesuada est, eu pharetra sapien mollis at.</p>

            <h2>Nam accumsan dui at neque malesuada</h2>

            <p>Curabitur vitae neque a lacus malesuada porta. Sed non condimentum risus. Nam malesuada, erat quis facilisis consectetur, neque felis varius ante, vel egestas dui urna a diam.</p>

            <ul>
                <li>Aenean tincidunt, nibh vel sodales malesuada, nunc sapien consequat dui, eu auctor ante tellus eu purus.</li>
                <li>Sed ut leo metus, in interdum libero. Proin sagittis augue at justo vehicula commodo interdum libero ullamcorper.</li>
                <li>Vivamus quis felis at ligula sollicitudin adipiscing. Sed semper faucibus ligula, sit amet luctus mi interdum at. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos.</li>
            </ul>

            <blockquote>Sed et tortor ante, vel mattis dui. Nam accumsan dui at neque malesuada id tincidunt quam faucibus. Maecenas tempus risus quis arcu suscipit eget ullamcorper diam scelerisque. Proin eleifend mauris quis magna pulvinar eget tempor massa fringilla. Aliquam erat volutpat. Praesent gravida luctus diam, eu scelerisque elit rutrum vel.</blockquote>

            <h3>Pellentesque convallis magna ut tortor mollis</h3>

            <p>Sed risus dolor, imperdiet nec pulvinar in, accumsan ac ipsum. Nullam adipiscing iaculis tempus. Nulla ornare neque non est ornare ac ornare ligula pretium. Donec lacinia condimentum ligula, in posuere arcu aliquam quis. Donec in nunc turpis. Proin nec leo in nulla ullamcorper laoreet. Cras ac justo elit. Duis a mauris purus. Sed eleifend urna non sapien porta ornare scelerisque massa facilisis. Duis mollis, elit et posuere imperdiet, elit sem tempor justo, non consectetur eros odio id urna.</p>
        </div>

        <div id="footer">
            <p id="copyright">Copyright &copy; 2009 by </p>
        </div>

    </div>
</body>
</html>

CSS

I begin my main all.css file with Eric Meyer's reset stylesheet, and you probably should too. I have it compressed onto one line to save space:

/* Eric Meyer's Reset styles */
html,body,div,span,applet,object,iframe,h1,h2,h3,h4,h5,h6,p,blockquote,pre,a,abbr,acronym,address,big,cite,code,del,dfn,em,font,img,ins,kbd,q,s,samp,small,strike,strong,sub,sup,tt,var,b,u,i,center,dl,dt,dd,ol,ul,li,fieldset,form,label,legend,table,caption,tbody,tfoot,thead,tr,th,td{margin: 0;padding: 0;border: 0;outline: 0;font-size: 100%;vertical-align: baseline;background: transparent;}body{line-height:1;}ol,ul{list-style:none;}blockquote,q{quotes:none;}:focus{outline:0;}ins{text-decoration:none;}del{text-decoration:line-through;}table{border-collapse:collapse;border-spacing:0;}

Next, I reset my base font-size using a percentage of the browser-default 16 pixels. From this point on, I use ems to adjust the size of particular elements as needed. I also set a default line-height here, which helps ensure a consistent baseline-grid. While I'm at it, I set a default font on both the body and a variety of form-elements, which tend to have trouble with inheritance.

body {
    font-size: 87.5%;      /* Reset base size to 14px */
    line-height: 1.429em;  /* Reset line-height to 20px */
    }

body, input, textarea, select, label {
    font-family: Helvetica, Arial, Geneva, sans-serif;
    }

Next, I have empty declarations for many of the common html elements. Having them all there to begin with keeps me from forgetting to style anything. You can construct your own list of the element use typically use, but one default declaration that I alway keep in there is for the img element. Internet Explorer 6 does a terrible job of resizing images unless you set img { -ms-interpolation-mode: bicubic; }.

Finally, I list IDs of everything that I have in my default html template—#header, #nav, #content, #footer, etc. By organizing them all in the template, I have a good starting point for styling the final site.

JavaScript

My default html template includes calls to two libraries that I use on almost all my projects. The first is the Google Code-hosted copy of jQuery. jQuery makes my life easier in lots of ways, and the Google-hosted version is faster to load (and more likely to be cached already) than a local copy. The second script I start with is DD_BelatedPNG, which fixes png alpha transparency in IE6. Although there are many png-fixing scripts out there, this is the least-buggy one I've found and one of the few that supports background-position and background-repeat. I keep a copy of BelatedPNG in the scripts folder of my template site.

Finally, I use a default site.js script with a few commonly-used jQuery mini-plugins. I don't use these on every site, but often enough that I don't want to re-write or hunt them down every time. If I don't need them for the project I'm working on I just delete them. The particular scripts I include in site.js changes from month to month, but here is what I've got in there right now:

$(document).ready(function() {

    // Open external links in a new window
    $('a[href^="http://"]').attr("target", "_blank");

    // Clear textboxes on focus
    $('.autoclear').autoClear();

    // Setup the nav drop-downs
    $('#nav').dropDown();

});


// Clears the default text when an input receives
// focus and reinstates it if it is left blank
(function($) {

    $.fn.autoClear = function() {	
        return this.each(function() {
            $(this).focus(function() {
                if( this.value == this.defaultValue ) {
                    this.value = "";
                }
            })
            .blur(function() {
                if( !this.value.length ) {
                    this.value = this.defaultValue;
                }
            });
        });
    };

})(jQuery);


// Sets up an elements's children as drop-down menus
(function($) {

	$.fn.dropDown = function(options) {

		// build main options before element iteration
		var opts = $.extend({}, $.fn.dropDown.defaults, options);

		// iterate each matched element
		return this.each(function() {
			menu = $(this);

			// Show the submenus on click
			menu.children('li:has(ul)').hover(
				function() {
					$(this)
						.addClass(opts.active_class)
						.children('ul').animate(opts.show, opts.show_speed);
				},
				function() {
					$(this)
						.removeClass(opts.active_class)
						.children('ul').animate(opts.hide, opts.hide_speed);
				}
			).children('ul').hide();
		});
	};

	// Default options
	$.fn.dropDown.defaults = {
		show: {opacity: 'show'}, 	// Effect to use when showing the sub-menu
		show_speed: 300,			// Speed of the show transition
		hide: {opacity: 'hide'}, 	// Effect to use when hiding the sub-menu
		hide_speed: 200,			// Speed of the hide transition
		active_class: 'open'		// Class to give open menu items
	};

})(jQuery);

Update: Since I wrote this post I have updated my Drop-Down Menu script to be more flexible and bullet-proof.

Conclusion

Don't just copy the code I've included here. You should look back through the last few websites you have created and pull out anything that you find yourself using frequently. When in doubt, include more template code rather than less. Remember that it is always easier to delete code you don't need for a particular project than to re-write code that isn't in your template site.