Blog

Where we discuss our work, thoughts, and process

Lazy Development: Using Templates to Save Time

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.

Comments

's avatar
John Hamelink

Thank you for this article - I will definitely be using this idea in the future :)

John Hamelink,
http://syntaxmonster.net

's avatar
Mark McDonnell

I just wanted to comment on your sentence...

"I begin my main all.css file with Eric Meyer's reset stylesheet, and you should too."

...I disagree on the grounds that you are assuming that a Reset.css stylesheet is actually a good practice. I personally don't find them that useful and actually my CSS gets bloated when I have used a Reset stylesheet! See Snooks article on this which I'm happy to see I'm not the only one who has issue with Reset stylesheets http://snook.ca/archives/html_and_css/no_css_reset/.

The fact that you use a Reset stylesheet is fine, and isn't a problem in itself but it raises an issue when you're giving out the impression that using one is a 'best practice' when that isn't completely true and using one is more a personal preference and doesn't necessarily make your CSS any easier to write (again see the above article link from Snook for a more detailed explanation on the extra code bloat).

This is a minor issue for most but something I feel was worth mentioning for those new to CSS who may take what you've writted as 'gospel'.

Kind regards

's avatar
Dave Sparks

A starting template is a good idea. I have one myself which sets up my standard set of CSS, site structure and javascript, including stuff like super sleight which I nearly always include.

's avatar
Eli Van Zoeren NMC team member

Mark:

That is an interesting point. I find that even when I don't use an explicit reset stylesheet, I end up resetting most of the same properties on any elements I use anyway. So it saves me time to just do it automatically on every project. Also, you mention css beginners. In my experience, not using a reset stylesheet causes a huge amount of frustration for most beginning front-end developers.

That said, I would never want to discourage people from thinking for themselves. So I qualified the above as: "you probably should too". To each their own!

Thanks for reading and sharing your thoughts.

's avatar
Russell Bishop

Great article! Until now I've simply duplicated the last website I built and stripped out the parts that made it unique, but this "covering all bases" approach seems like a much more unified method.

's avatar
vince

This is a practice that I have been doing for a while. It saves so much time.

As for the CSS Reset stuff, from experience, I highly recommend a reset. Why? Because it's usually less time in IE6/7.

Sure you can not use a reset and deal with things as they come but I have a strong feeling more time will be spent developing for cross-broswer nonsense.

Anyways, great article!

Leave a comment

Real Time Web Analytics