I am not a designer now I will never be a designer. I don't have the talent or the patience for it. Unfortunately my very close proximity to a designer for the past 10+ years has led me to tend to place a higher value on how things look than I did previously (or would probably prefer).



This becomes an issue early in the development process when a web project is in it's beginning stage and tends to look like the illegitimate offspring of some jurassic-era reptiles. Sometimes we'll work from some nicely designed mockups, but for larger development projects, designing screens first and functionality later ends up being too constraining for the inevitable iterative spec changes that come down the line (see: Specs: The Consultant's MacGuffin ).

I would rather have some flexibility in developing the specific interface elements rather than be limited to an initial design mockup. Likewise, designers usually prefer or should prefer to have a good idea of all the elements that will needed to be in a site before really spending the time to generate a find-tuned design, so developing first and (graphically) designing later is a win-win.

... spending 8 hours a day working with something that looks like absolute garbage is incredibly demotivating.

Except that spending 8 hours a day working with something that looks like absolute garbage is incredibly demotivating. The default styles of most web browsers make simple markup look terrible. The good news is that the amount of effort it takes to make a HTML web application look half-way decent is pretty easy, more or less transferable from project to project, and doesn't add complexity that you'll regret later.



Simply applying a simple header and footer along with a couple of class names to your elements along with a basic CSS file will go a long way towards making your application output prettier and easier on the eyes. I'm going to take three examples of non-styled output and go through a couple of easy steps to make them look a lot nicer: a piece of content, a form and a table. If you're already pretty comfortable with CSS there's not a lot new here, other than the idea of getting some styles in earlier in the process than might be usual (click each image for the html version)

We're going for 4 basic rules to do this:

1. No defaults - just like most people still surf with IE because it's pre-installed there's a lot of websites that don't override the default styles. These are usually the websites that look like a 4-year-old's refrigerator drawing so when I see nothing but Times New Roman it looks like they didn't even try - unless they are doing it on purpose.

2. Differentiation - different elements should look different, so give elements like table cells one look and table headers a very different look - don't just make it bold or one point bigger - give it a background and make it way bigger. When two elements look too similar it ends up looking like either a mistake or just bad design.

3. Grouping - related elements should be grouped together as it makes it easier to tell what's connected on a page. That means adding extra padding between your paragraphs and columns. Pull up a well designed site in your browser and notice how easy it is for your eyes to scan around the different components of the page. Now look at your page - same thing?

4. Whitespace - in general the more the better. Properly spacing elements is the easiest way to improve the look of a site and make it look more professional - remember - when in doubt, pad it out. This is very connected to grouping but worth mentioning separately. White space invites the eye into to read the content.

We're also going to apply 1 meta rule to consider the entire time: apply the rules above but stay consistent throughout the whole site - nothing looks worse than a mishmash of 60 different colors, fonts, sizes and spacing. So - apply the rules above, but do it in a consistent way - using just a couple different fonts, font sizes, colors, and background colors will make everything a lot easier on the eyes.



My designer gives me 1 baseline guideline: pick two fonts and three sizes and unless you know what you're doing stick to that or the site may start to look messy.

Getting a blank slate



First things first - give yourself a decent doctype to make sure you are turning on "strict" mode so that you have some sort consistency across browsers:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">



Next pull in some sane defaults into your CSS file:

/* Reset all white-space to 0 for consistency across browsers */

* { margin:0px; padding:0px; }



/* Default to some sans-serif font at a specific size */

body { font-family: Verdana, Arial, sans-serif; font-size:12px; }



/* Get some padding between paragraphs and some line spacing */

p { padding-bottom:5px; line-height:1.4em; }



/* Put some padding back onto our list elements */

ul, ol { margin-left: 10px; }

li { margin-left:10px; padding-left:10px; }



/* Bye bye ugly blue border */

a img { border:0px; }



/* No dots around clicked links */

a, a:active { outline: none; }



/* Class to any floated elements */

.clear { clear:both; }

Giving the page some structure



Now you can do some more involved resets , but I've found these 8 lines of CSS are a good start.

Next lets wrap the each of our pages in some sort of template - unstick stuff from the top left of your browser. If you have an idea what target width your website is going to be (many websites these days are fixed width as it's easier to control how stuff looks, but there are plenty of exceptions) you might as well put something in there so that you can get an idea of how much content will fit on the screen at once pretty early in the process. If you are going to have a sidebar (or think you might) put one is as well so that you're working with a realistic sized canvas for your dynamic data. Some sort of dummy navigation that you can swap out as new things are added in will help as well. Depending on how you're developing you might have a layout template or a separate header and footer templates:

<div id='container'>

<div id='header'>

<div id='logo'><a href='/'><img src='images/logo.png'/></a></div>

<div id='tagline'>Lorem Ipsum, dolor sic Amet!</div>

</div> <!-- end #header -->

<div id='main_menu'>

<ul class=menu'>

<li><a href='#'>Item 1</a></li>

<li><a href='#'>Item 2</a></li>

<li><a href='#'>Item 3</a></li>

<li><a href='#'>Item 4</a></li>

</ul>

</div> <!-- end #main_menu -->

<div id='content_container'>

<div id='sidebar'>

<div class='sidebar_heading'>Some Heading!</div>

<div class='sidebar_body'>Lorem ipsum dolor sit amet, consectetur adipiscing elit.</div>



<div class='sidebar_heading'>Second Heading!</div>

<div class='sidebar_body'>Lorem ipsum dolor sit amet, consectetur adipiscing elit.</div>

</div> <!-- end #sidebar -->

<div id='content'>

<!-- Content Goes Here! -->

</div>

<div class='clear'></div>

</div> <!-- end #content_container -->

<div id='footer'>

<div id='copyright'>© 2009 Acme Co</div>

</div> <!-- end#footer -->

</div> <!--end #container -->

Now lets drop in a few lines of CSS to center and pad our page out and give it a little structure:

/* Set the width to 900 pixels, centered on the page with a little padding on top */

#container { width:900px; margin:0 auto; padding-top:10px; }



/* 90 pixels to work with at the top - positioned relative so that we can absolutely position our header elements easily */

#header { height:60px; position:relative; }

#logo { position:absolute; left:0px; top:0px; }

#tagline { position:absolute; right:0px; top:5px; color:#666666; font-size:14px; font-weight:bold; }



/* Quick right-aligned tab-looking text menu */

/* Make sure to be explicit with the padding and margin on our ul and li elements so we can change the defaults later on as necessary */

#main_menu { height:26px; border-bottom:3px solid #000000; margin-bottom:30px; }

#main_menu ul { display:block; float:right; list-style-type:none; padding:0px; margin:0px; }

#main_menu li { display:block; float:left; margin:0 5px; padding:0px; }

#main_menu a {

display:block;

float:left; /* Needed for IE */

padding:5px 20px;

color:white;

background-color: #000000;

text-decoration:none;

}

#main_menu a:hover { color: #000000; background-color:#666666; }





#content_container {

padding:10px 0px;

border-bottom: 1px solid #CCCCCC;

/* Do the IE hack to get a minimum content container height */

height:auto !important;

height:500px;

min-height:500px;

}



/* Floating left and then right means that we can play with the widths of the sidebar and content separately and not worry about explicitly setting the space between */

#sidebar { float:left; width:200px; }

.sidebar_heading { font-weight:bold; padding-bottom:2px; border-bottom:1px solid #CCCCCC; margin-bottom: 5px;}

.sidebar_content { padding-bottom:10px; }

#content { float:right; width:650px; }



#footer { height:20px; position:relative; }

#copyright { position:absolute; top:5px; right:0px; font-size:10px; color:#999999; }





Here's our three pages with the defaults CSS file and a little bit of structure added to them - already slightly better - they are starting to feel like a website and not something months away from being usable (click to go to the actual html files)







Ok, now let's go through each page one at a time and try to make them look a little nicer, starting with the piece of content.

Reworking content page

Let's attack the CSS for the content:

First, make the header stand out with a color, some padding and a larger size.

Second, fix the information line closer to the header, make it smaller and lighten it up a little.

Third give our image some padding so the content isn't stuck to it.

/* Content Styles */



h1 { color: #333333; padding-bottom:15px; font-size:26px; }

.content .info { position:relative; top:-17px; font-size:11px; color:#999999; font-style:italic; }

.content img { float:left; padding:0px 14px 10px 0px; }

p { color:#444444; }





That was easy, no? Content already looks significantly better and will be nicer to work with as it continues to get developed:

Reworking the form



<form action='...' method='post'>

<div class='horizontal_form'>

<div class='header'>Basic Information</div>

<div class='item'>

<div class='label'><label for='first_name'>First Name:</label></div>

<div class='data'>

<input name='frm[first_name]' type='text' id='first_name' class='text_field' size='30/>

</div>

<div class='description'>Enter your first name</div>

</div>

...More Items and headers...

</div>

</form>



Next onto our form. With forms, grouping is the most important rule to follow, so that's it easy to tell what's related to what. Now there are different styles of markup your can use to create your forms - for simplicity's sake lets assume you're using a div's and not a table, but either way works. You might have a form markup that looks something like:

Note - Some people have taken some serious issues with the use of divs, especially in the form elements (I even have a disease), so take a look at Prettier Accessible Forms for an alternative. I'm not a huge fan of that layout style, and I generally avoid fieldsets and legends like the plague because of the difficulty in styling them. I don't mind some extra divs around as it makes flexibly modifying forms via css simpler and cleaner and is easier to generate via code (I come from a cms background where we don't know what content is going where so a bunch of carefully crafted "#footer p img { position:absolute .. }" styles are worthless to me), but take a look the A List Apart post as a start and find what works for your project.

If you're targeting ie6 you'll need to add that extra classname to your input elements somewhere to tell you what input type your dealing with, otherwise you can use input[type=text]



Let's take quick stab at some css for a horiztontal (labels next to elements) form. Here's what we're going to do:

right align the labels and put the description stuck below the field (grouping) padding out the elements a little (whitespace) separate out the headers (differentiation, grouping and whitespace) give the whole form some padding all around (whitespace) get rid of the default border and add in a psudeo-class when the field is focused. (no defaults) Align and Pad out the button a little bit - make it easier to click and a little less default-looking.



a few lines of CSS should do the trick:

/* Form Styles */

.horizontal_form .item { margin:10px 4px; }

.horizontal_form .item .label {

width:150px;

text-align:right;

float:left;

padding-right:10px;

vertical-align:baseline;

padding-top:3px;

color:#666666;

}

.horizontal_form .item .description {

clear:both;

padding-left: 160px;

font-size:11px;

color:#aaaaaa;

font-style:italic;

}

.horizontal_form .item .text_field {

border:1px solid #999999;

padding:2px 2px;

color:#666666;

}

.horizontal_form .item .text_field:focus {

background-color:#eeeeee;

}

.horizontal_form .header {

margin:15px 0px 10px 0px;

padding-left:0px;

font-size:16px;

border-bottom:1px solid #CCCCCC;

font-weight:bold;

color: #666666;

}

.horizontal_form .button { margin-left:200px; padding-top:10px; }

.horizontal_form .button input { padding:4px 10px; }

And we're done:

Reworking the table



Already much better, and what's nice is because this was all done with CSS a couple of rule changes and the form can look completely different.

Finally let's take care of the table, here's what we're going to do:



1. Get rid of cellspacing and cellpadding

2. Highlight the headers and pad them out a little bit

3. Give the table cells a consistent padding on the left and right as well as top and bottom.

4. Add in some sort of separation - either a thin border between rows or a striping effect (or both) looks nice.

/* Table Styles */



table.account_table { border-collapse: collapse; }

table.account_table th {

padding: 10px 10px;

color:white;

font-size:14px;

background-color: #7caaff;

font-weight:bold;

}

table.account_table td {

padding: 6px 10px;

border-bottom:1px solid #999999;

}

table.account_table tr.odd td {

background-color:#eeeeee;

}

table.account_table td.currency { text-align:right; }



And we're done:





Now, you're not going to replace your designer in your organization (nor should you want to, programmers are much better paid) - but at least your work-in-progress will look a lot nicer. The point of this tutorial, and of creating a very basic, black and white site was to show you how little design knowledge and creativity is necessary to make something look halfway decent. Your not going to win any awards, but I bet you get a better reaction from the client with a couple minutes of simple CSS styling than you do from the entire week you spent getting getting that complex javascript validation to work correctly.



There's one thing that you need to be careful about making things look too finished too early - your client was often assume that the better something looks the closer it is to being done. So, for parts of the project that aren't anywhere near being done, make sure there is a stark contrast with the parts that are approaching completion - put a big X through them or give them a grayed out background. (See: Joel on Software's post The Iceberg Secret which talks the issues with having something look "done" when it's not).

Side note: Some people have mentioned the use of CSS frameworks, such as 960 Grid System. I'm don't like those from a developer's perspective as they leak a lot of information about your layout and design into the HTML of your site, where I don't think it belongs (this is especially true if a designer is going to come in and rework the design: you don't want to rewrite all your HTML to support a new design). They are also "heavy" in that you need a lot of css to set up the grid and what you can change by only modifying the CSS is more limited. I like the css Zen Garden philosophy a lot better - separate your content as completely as possible from the design and layout - but to each his own (aka "Flame On!")