The 960 Grid System is a CSS framework that allows for easy implementation of most any type of layout using only a few classes. The basic usage behind 960 requires a fixed layout of 960 pixels. There are two grid systems that can be used: a 12-column grid layout or a 16-column grid layout. The design we are working on, our KISS Template, uses the 16-column layout (12 would have worked just as well). Before we start implementing our layout using our KISS slices let’s first examine a few points regarding 960 GS.
Post Outline:
- The 12-column and the 16-column grid setup
- alpha and omega classes
- prefix and suffix classes
- clear class
- Building our HTML for the KISS Template
- The CSS
The 12-column and the 16-column grid setup
960 GS allows for two setups: the 12-column layout and the 16-column layout. The differences are not in total width (both are 960 pixels wide) but in grid width. The 12-column layout has a grid-width of 60 pixels while the 16-column layout has a grid-width of 40 pixels. Each grid has an outside margin of 10 pixels. So you’re outside grids (grids 1 and 12 for a 12-column layout, or 1 and 16 for a 16-column layout) have only a 10 pixel margin on the outside. However, in between grids there is a spacing of 20 pixels, gutters. You can see this clearly in the 960GS demo. The gutters are your margins. They are not altered when you work on your CSS nor should you attempt to alter them. They are there to provide a sleek vertical flow to your content. Altering them in the style sheets can cause nasty effects in your remaining layout.
So, how do you set up your columns? First, in your HTML file you should create a div and assign it the id container_16 for a 16-column layout or container_12 for a 12-column layout. All of your additional divs will be placed within container_12 or container_16.
In your CSS file you’ll assign the class .container_12 or .container_16.
.container_12 {
background: #fff url(img/12_col.gif) repeat-y;
margin-bottom: 20px;
}
.container_16 {
background: #fff url(img/16_col.gif) repeat-y;
}
Each column or grid also is assigned a number in relation to the number of columns or grids you wish to span. For example, using a 16-column layout if I assign a div the class grid_1 my div will span one grid or column and be exactly 40 pixels wide. If I assign that same div the class grid_2 that div will span two grids in addition to the margin-space. That div would actually be 100 pixels wide (40 pixels * 2 grids + 10 pixel margins to the right of the first grid and to the left of the second grid). grid_3 would span 160 pixels. grid_4 would span 220 pixels. You can see this in the demo. In a 16-column layout you can use up to grid_16. In a 12-column layout you can use up to grid_12.
While in development you should feel free to set your background image to the grid layout you have chosen. This aids in development so you can see exactly where your divs are being placed and helps keep all of your elements streamlined. These images are located in the /code/img/ directory where you unzipped your 960 files. All of the css and img files are necessary. All you should do is decide if you want the compressed files or the uncompressed css files. For the remainder of this tutorial I will be writing links based upon my directory structure on my local server. It is as follows:
- /tutorials-kiss
- index.html
- /css/
- 960.css
- reset.css
- text.css
- style.css
- /img/
- all of my sliced images and my grid background
Notice that I have created a new style sheet, style.css. This is where I will place my additional CSS definitions. Before we proceed there is one more thing I wish to stress. You should never write additional CSS for grid classes. I’ve assigned each of my div’s an ID that I will reference when I create my custom CSS. You should not try to reposition these ID’s with elements such as negative margins or floats. There is no need. Hopefully by the end of this tutorial you will see it is very easy to do whatever you want within the 960 grid system. Who knows? You may never fear CSS again after this!
alpha and omega classes
alpha and omega are classes that will be used quite a bit. They are used in instances where you are embedding grid divs within another grid div that appear in the same row. For example, such an instance would be our header for our KISS Template. We want our name and slogan to appear block style and even with our search form in the middle and our logo on the far right. It’s easier to embed the name into a separate grid from the slogan as far as styling and layout goes. By another example, let’s say we have a 5-link navigational menu directly beneath our header. We may decide to include each link inside it’s own div but also those divs inside one larger div. We should tell 960GS which grid is the first and which is the last.
<div class="container_16"> <div class="grid_16">.grid_16 header <div class="grid_2 prefix_3">Menu 1</div> <div class="grid_2">Menu 2</div> <div class="grid_2">Menu 3</div> <div class="grid_2">Menu 4</div> <div class="grid_2 suffix_3">Menu 5</div> </div><!-- end grid_16 --> </div><!-- end container_16 -->
The above code produces the following output:
Soon we’ll get into the use of prefix, suffix and clear classes. Notice that besides our Menu 5 item resetting to the next “row” that each menu item takes an additional ten pixel margin from the left. This can cause us to lose horizontal space, identified here by the Menu 5 item being displaced. By assigning alpha to Menu 1 and omega to Menu 5 we tell 960 that these are the children of header. This gives us our ten pixels back and let’s us keep our menu items on the same row.
<div class="container_16"> <div class="grid_16" id="wrapper"> <p>wrapper</p> <div class="grid_2 prefix_3 alpha"> <p>Menu 1</p> </div> <div class="grid_2"> <p>Menu 2</p> </div> <div class="grid_2"> <p>Menu 3</p> </div> <div class="grid_2"> <p>Menu 4</p> </div> <div class="grid_2 suffix_3 omega"> <p>Menu 5</p> </div> </div><!-- end wrapper --> <div class="clear"></div> </div><!-- end container_16 -->
In this example, we certainly could have just put our menu divs outside of header. But when you start styling there could be several reasons why you would want to embed navigational menus. It’s important to remember when you’re alignment starts looking misaligned the first place to look is at your embedded child divs to see if you’ve properly assigned alpha and omega.
prefix and suffix classes
In our previous example we used instances of both prefix and suffix on Menu 1 and Menu 5. prefix is padding an element to the left by a particular number of grids. In our example, we padded the element by three grids. suffix is padding to the right. We can pad up to 15 grids or columns because, naturally, our 16th grid will contain content. Is padding necessary? In some instances, yes it is. You could create a div and assign it the class of grid_3 and insert the whitespace character (you must insert the whitespace character else the row will collapse to the left). That’s unnecessary typing, though. However, there are some issues you should be aware of when working with prefix and suffix. Let’s say you wanted to assign the background-color of Menu 1. You might attempt to do so with the following:
<div class="container_16"> <div class="grid_16" id="wrapper"> <p>wrapper</p> <div class="grid_2 prefix_3 alpha" style="background-color: #CCCCCC;"> <p>Menu 1</p> </div> <div class="grid_2"> <p>Menu 2</p> </div> <div class="grid_2"> <p>Menu 3</p> </div> <div class="grid_2"> <p>Menu 4</p> </div> <div class="grid_2 suffix_3 omega"> <p>Menu 5</p> </div> </div><!-- end wrapper --> <div class="clear"></div> </div><!-- end container_16 -->
The problem is that because your div is padded your entire div will be colored gray. Not just the Menu 1 box. We can easily adjust this by assigning the background-color to the p element instead. Our entire Menu 1 box would be colored gray, but nothing else. Situations will vary and there may be a use where you can’t use prefix or suffix due to styling restraints. As you play around with 960 you’ll quickly get the hang of what you can and can’t do. Just keep in mind if you are using prefix or suffix and you have visual elements appearing outside of your desired area then perhaps you should consider inserting another div with the appropriate grid class.
clear class
By assigning a div the class clear we are simply using the default behavior of the clear method in CSS. When does it typically come in to play? It’s use, from my research, is when you wish to tile background imagery. In addition, we can also use it in cases where we don’t fill up a typical row.
<div class="container_16"> <div class="grid_15"><p>grid_15</p></div> <div class="grid_1"><p>grid_1</p></div> <div class="grid_15"><p>grid_15</p></div> </div>
By writing this code it may have been my intention to have the first grid_15 on the first row with grid_1 and grid_15 on the second row. But this will not be the result. Because grid_1 can fit on the first row behind grid_15 that is exactly where it will go. If I wanted to force a reset of grid_1 to the second row, I would add:
<div class="container_16"> <div class="grid_15"><p>grid_15</p></div> <div class="clear"></div> <div class="grid_1"><p>grid_1</p></div> <div class="grid_15"><p>grid_15</p></div> </div>
By adding clear we push grid_1 to the second row. Now, in this example we now have a lopsided header bar that I’m sure would be useful for something but not for us. So let’s move on.
Building our HTML and CSS for the KISS Template
Now we get to the fun stuff: actually designing our template. The first thing we should start with is a basic naked layout. We can set up all of our divs without inserting our intended content and other formatting elements. All I will be doing is labeling each div after my id which I will assign to it and stroke the div with a 1 pixel solid black border.
Let’s think about our layout for a second. In the broad scheme of it our layout only consists of four main rows: our header, main content, secondary content and then footer. Of course, each of these will have rows embedded within, but basically speaking…
We also have three main columns: our left gradient, our wrapper and our right gradient. Of course, our wrapper will have additional columns embedded. Our header will have three itself. Afterwards, however, we will only be using two. I’m not specifying grid usage here. I’m simply giving a broad glimpse of the overall scheme of our layout. I’m starting with the broader picture and working my way up. So let’s start with the broadest of all – the container.
The Container
As mentioned earlier, we are using a 16-column layout that must be identified first in our HTML by assigning a div the class container_16. You must assign this class first else your HTML will not work. All of our additional div’s will be buried within this div. If you want to get really tricky you can use both classes of container; just not embedded within each other. That’s for another day, though.
In our CSS file we assign container_16 the basic property of a background image; our col_16.gif image (this image comes with the 960 download in /code/img/. We also assign the properties for the p element so that we can see where our grids line up.
.container_16 {
background: url(../img/16_col.gif) top left repeat-y;
}
p {
border: 1px solid #666;
padding: 10px 0;
text-align: center;
}
This will help us follow our layout and make sure we are staying within the boundaries so that we can use the full 16 columns. Our plan is to have a gradient background image, 960 pixels wide, that repeats vertically. When we created our layout we did so with both our left and right gradients stretching a full div on each side. So right off the top we lose two grids leaving us with 14 to work with. We do not need to specify our first div a grid_1 for the gradient. We can easily use prefix and suffix. Note that from this point forward all HTML coding will be inside the div container_16.
<div class="grid_14 prefix_1 suffix_1" id="wrapper"> <p>wrapper</p> </div><!-- end wrapper -->
When you load your page you should see something like this:
Notice we have our two grids (the pink columns) on the left and right where our gradient background will go. The background image itself, by the way, will replace the grid when we are complete. We do not need to add any additional grid div. Also be aware we used a clear div to bring the background image to the bottom of our layout. Without that, we would have no background. From this point forward, everything we do will be inside div wrapper.
Next we should create our header where our website name, slogan, search form and logo will appear. header will expand the full 14 columns we have at our disposal by assigning the div the additional alpha class since it is the first child under wrapper. When we create this div (and give it text in a p element, “header” we will see an identical box to wrapper appear just below wrapper. Do not worry about this. We’ll remove the wrapper p element (not to be confused with Master P
) header will move up and take wrapper’s place while still staying inside of wrapper. Confusing? Go ahead and remove the wrapper p element and see.
Next we work on our second row which will contain our primary content and our navigational menu. We’ll do this the same by creating a div and assigning it the class grid_14 alpha and give it the ID main_content. While you’re at it, create another div with the same class and give it the ID secondary_content. And then, lastly, a div with the class grid_14 omega (this is the last child of wrapper) and give it the ID footer. None of these divs should be embedded within each other. Yet, all should be embedded within container wrapper. Your HTML will look like this:
<div class="grid_14 alpha" id="header"> <p>header</p> </div><!-- end header --> <div class="grid_14 alpha" id="main_content"> <p>main content</p> </div><!-- end main_content --> <div class="grid_14 alpha" id="secondary_content"> <p>secondary content</p> </div><!-- end secondary_content --> <div class="grid_14 alpha" id="footer"> <p>footer</p> </div><!-- end footer -->
We added alpha to each of our div’s because they are not on the same row, but still children of wrapper. Remember you only need to use omega if the child div is to appear on the same row as the div you assigned alpha.
Your results should look like this:
And, just like that, our container is done!
Website Name and slogan
Now that we have our body outline done we can start working in the header. All div’s for our website name, slogan, search form and primary logo will be included in header. Starting off with our website name and slogan we want it to span seven columns or grids. Our search form is pretty small so it will take up two grids leaving five to insert our logo. We will start of creating three grids inside of header. We will name our website name and slogan grid ID site_info and assign it the class grid_7. In addition, we also must assign alpha since it is the first grid in our header row. Then we will create our search grid and assign it the ID search with the class grid_2. Because this is our middle child we do not need to assign it alpha or omega. Lastly our logo div will get the assignment grid_5 omega. Your final HTML (all within header) will be:
<div class="grid_7 alpha" id="site_info"> <p>site_info</p> </div><!-- end site_info --> <div class="grid_2" id="search"> <p>search</p> </div><!-- end search --> <div class="grid_5 omega" id="logo"> <p>logo</p> </div><!-- end logo -->
Note that I’ve also removed the header p element to remove the header text that was originally appearing. Our website should now look like this:
It does appear search may be a little too small. We can choose to either take a grid off from site_info or logo. Being that we should keep site_info dominant, I made an alteration and changed search’s class from grid_2 to grid_3 and changed logo’s class from grid_5 to grid_4. We will have to adjust our image size when we insert it but that’s ok.
Now I will move my focus to site_info. I will have two divs inside site_info – one for site_name and one for site_slogan. Both divs will be it’s own row and both will have the class grid_7 assigned in addition to alpha. Working inside site_info I write this HTML coding:
<div class="grid_7 alpha" id="site_info"> <div class="grid_7 alpha" id="site_name"> <p>site_name</p> </div><!-- end site_name --> <div class="grid_7 alpha" id="site_slogan"> <p>site_slogan</p> </div><!-- end site_slogan --> </div><!-- end site_info -->
My output:
I want to point out that while it may appear that site_slogan will appear beneath search and logo this will not be the case. site_slogan will keep it’s positioning as long as the bottom margins of search and logo do not pass the bottom margins of site_slogan. Should that occur then site_info will expand vertically to keep equality with search and logo. In other words, all three core elements, site_info, search, and logo will maintain the same height. They are all confined within header which you see in the above image surrounded by the red border. When we get to using CSS we can position search to appear vertically-aligned with header. That will come later.
Now that we are finished with header we can move on to main_content.
Main Content
main_content will be just as simple as header to build. We have two core elements to main_content, content and nav, or navigation menu. content will be padded from the left by one grid and from the right by two grids. nav will not have any left padding but a right padding of one grid. You should already find it very easy to construct the HTML but let me point out a couple of things. In our original PSD layout we padded content with one grid and spanned it seven grids. That leaves us five grids to add our navigation menu. This seems like quite a bit and I don’t think now that I need so much spacing.
Let’ assume that I wanted to drop navigation menu to four grids. That gives me 100 pixels for my left navigation menu and another 100 pixels for my right navigation menu. That is certainly long enough for most links. By dropping nav to four grids I can also increase content by one grid. I can keep my spacing in between content and nav. In addition, I can have more spacing in content to either insert more content (though not much) or keep the same amount of content but allow secondary_content to appear higher in the viewport and be more visible. I like that idea much better.
<div class="grid_14 alpha" id="main_content"> <div class="grid_8 prefix_1 alpha" id="content"> <p>content</p> </div><!-- end content --> <div class="grid_4 suffix_1 omega" id="nav"> <p>nav</p> </div><!-- end nav --> </div><!-- end main_content -->
nav
With four grids to work with we’ll need to divide lft_nav and rgt_nav into two grids each. Because both lft_nav and rgt_nav are children appearing on the same row under nav lft_nav will also be assigned alpha and rgt_nav will be assigned omega.
<div class="grid_4 suffix_1 omega" id="nav"> <div class="grid_2 alpha" id="lft_nav"> <p>lft_nav</p> </div><!-- end lft_nav --> <div class="grid_2 omega" id="rgt_nav"> <p>rgt_nav</p> </div><!-- end rgt_nav --> </div><!-- end nav -->
You should now have this output:
If you feel you’d rather have nav spaced one grid from content then change the class suffix_1 to prefix_1.
Secondary Content
Working on secondary_content will follow the same principals behind main_content only without the additional “complexities” of nav. Simply I assigned logo2 the grid_3 alpha class and content2 the grid_11 omega class.
<div class="grid_14 alpha" id="secondary_content"> <div class="grid_3 alpha" id="logo2"> <p>logo2</p> </div><!-- end logo2 --> <div class="grid_11 omega" id="content2"> <p>content2</p> </div><!-- end content2 --> </div><!-- end secondary_content -->
Footer
We conclude our wireframe with footer. As you can imagine it spans 14 grids.
<div class="grid_14 alpha" id="footer"> <p>footer</p> </div><!-- end footer -->
And this is where I say, “Voila!” We have finished our final wireframe for our layout.
Let’s pretty it up with some CSS.
The CSS
Here I won’t get into every detail of the CSS file (that will all be in the source code files at the bottom). Merely, I want to focus on the important aspects of really getting the effects I want.
I first start off back in site_info under site_name (which I put in an H1 element hyperlinked) and site_slogan (which I put under an H2 element).
<div class="grid_7 alpha" id="site_info"> <div class="grid_7 alpha" id="site_name"> <h1><a href="http://localhost/app/webroot/tutorial-kiss/" title="K.I.S.S.">K.I.S.S.</a></h1> </div><!-- end site_name --> <div class="grid_7 alpha" id="site_slogan"> <h2>(keep it simple, stupid!)</h2> </div><!-- end site_slogan --> </div><!-- end site_info -->
The CSS for this gets a bit tricky. It doesn’t require special features. But it does require the right font-size. Naturally we want this font to be as large as possible (within reason, I suppose). But, too large will force the text to break to another “row”. We want it inline. So we must figure out exactly how large we can go to have the text expand accordingly. I started off with site_slogan as the size of site_name is directly affected. Immediately I find that setting my font-size to 2.5em isn’t quite enough but 3em is too much ( the part, “stupid!)” resets to the next line). 2.75em works out pretty well but now I see that if I should choose to expand search by one grid to the left then site_slogan will break. I settle for 2.5em. I then set site_name to 3.25em and give it some stretching and weight. My CSS for both:
#site_name h1 a , #site_slogan h2 {
line-height: 1em;
}
#site_name h1 a {
font-stretch: 125%;
color: #c9b385;
font-size: 3.25em;
font-weight: 400;
text-decoration: none;
}
#site_slogan h2 {
font-stretch: 100%;
color: #194e76;
font-size: 2.5em;
font-weight: 400;
}
After applying additional formatting to search I move to main_content. I figure I’ll go ahead and apply my basic CSS to content and get that out of the way. But when I set my background-color I see that it’s covering the prefix_1 grid we assigned to it earlier. I had mentioned this would happen and, if so, we would have to add any empty div and assign it grid_1. I labled it the ID of spacer. My new HTML for content looks like this:
<div class="grid_1" id="spacer">&amp;nbsp;</div> <div class="grid_8 alpha" id="content"> <h3>Most Recently Kissed:</h3> <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Praesent ornare. Morbi porttitor placerat mauris. Aenean ornare neque vitae diam. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed ornare. Nulla purus ipsum, dapibus id, convallis tincidunt, adipiscing eget, risus. Nulla facilisi. Proin sit amet purus quis metus euismod ultrices. </p> </div><!-- end content -->
You may notice that my p element text has a black stroke with centered text. This is because of the earlier formatting we applied when building our wireframe. I’ve chosen to remove it but you can keep it if you prefer. I also want to apply a maroon stroke to content but we can’t just simply do that. Even a 1 pixel stroke will expand the width of content and consequently throw off nav to the next row. Instead, we’ll have to set content’s width specifically to account for the stroke. In addition, I want to add padding to my contents so i must take that into account as well. I chose to apply a stroke of three pixels. This is my CSS for content.
#content {
background-color: #C9B385;
color: #194E76;
border: 3px solid #8c0b0b;
width: 444px;
padding: 5px;
}
nav will require a little bit of testing to find out what works best. I wanted to create a zig zag pattern with all of my links centering around the 720 pixel vertical guide between grid 12 and 13, in the middle of a gutter providing a 10 pixel margin to each side. After assigning text alignments to both lft_nav and rgt_nav I don’t think I like how it looks compared to content and the outside region. I expand content to grid_9 and change the CSS width to 504px (444 pixels + the additional 40 pixel grid and 20 pixel gutter I am adding). This shifts the navigation menu one grid right much to my liking.
I continue using CSS to alter the appearance of the hyperlinks, enlarge the text and positioning each menu. I wanted a 40 pixel gap in between each of my menus to allow clear and easy navigation by the user. In addition, I had to offset the links in rgt_nav so they would create a nice balanced zig zag effect. I finished with the following CSS:
#lft_nav ul li , #rgt_nav ul li {
margin: 40px 0px;
list-style: none;
}
#lft_nav ul li a , #rgt_nav ul li a {
font-size: 1.15em;
text-decoration: none;
color: #8c0b0b;
}
#lft_nav ul {
text-align: right;
}
#rgt_nav ul {
text-align: left;
margin-top: 75px;
}
Of course, if you choose to add more than six menu links or take some away this will need some adjusting. If you were to go with five links you could simply remove the third menu from rgt_nav and have an arrow-effect on your menu.
The next major issue is doing the rounded corners for content2 and footer. I won’t go into detail as you can find a great tutorial by Trenton Moss over at Sitepoint. I applied my slices to each of the corner div’s, set my background color and padding then finishing up content2 with Lorem Ipsum and footer with simple copyright text.
Lastly, I went into my CSS and changed my background image in container_16 to my gradient background. This is the final result:










What are your thoughts?
by far your nicest, most organized tut. good job!
Nice run-through of the 960 grid. Good to see how others do things.
I noticed that several of your example .pngs are linked from ‘localhost’, so they are not showing to the public at large. Thought you’d like to know
Appreciate it very much, Jon. I always forget WP stores the full URL info in the database even with attachments. Something I desperately hope they’ll correct but never seem to do.
The screenshots for this article are gone. Apparently they weren’t included in the backup I had to restore after being hacked. I apologize and will fix as soon as possible
Last chance to get involved in the conversation...