Getting started coding without tables can be difficult. So you've read all the tutorials that teach you how to make a simple two column or three column layout but how do you make a real layout with actual content? How do all the elements in a tableless design work together? This guide will help answer those questions.
How to code a design without tables is a very expansive subject. There are many ways to complete any given task or achieve a desired result. The techiques presented here are the ones I use. I am always finding new and better ways to do things. You may already know a better way to complete a task than I do. Do whatever works best for you.
This layout has been tested in the following browsers: IE 6 on Windows 2000, Firefox 2 on Windows 2000, Netscape Navigator 9 on Widnows 2000, IE 5.5 on Windows 2000, Firefox 3 on Windows XP, IE 7 on Windows XP, IE 6 on Windows XP, IE 6 on Windows Vista, IE 7 on Windows Vista, Firefox 2 on Windows Vista, Opera 9.23, Safari 3 on Mac OS X, Safari 2 on Mac OS X, Firefox 2 on Mac OS X. These browsers together represent more than 99% of the browsers in use.
If you have already read some tutorials but don't quite get how a tableless design comes together this guide may help you. If you have been coding with tables for years like I have and are trying to transition to coding without tables, this guide may help you.
If you have never used any CSS before this guide may be to advanced for you right now. W3C.org has tons of examples that cover all the basics of working with CSS.
The guide goes rule by rule through all the CSS and markup used to create this design. The guide does not cover basic css formatting properties such as font-weight, font-size, color, background-color, etc... You should have some familiarity with these properties before beginning the guide.
Because of the intertwining nature of some of the concepts presented it may be advantageous to read over an entire section or even the entire guide before actually starting to work with the code.
The guide is broken down into the major sections of the design. At the beginning of each section you'll see the markup for that section followed by the CSS rules that apply to that section. After the rules are explanations of what each one is doing. Some basic formatting properties such as font-weight are not covered in the explanations unless they affect other other rules in a significant way.
Links with a grey background are reference links. Most lead to pages at W3C.org. There are various other links which lead to additional resources. These offsite links will open in a new window or tab depending on your browser and settings.
I laid out the guide in such a way that it is suitable for printing. In some case, the markup has been truncated to fit the page. Please refer to the coded design for the complete markup.
These styles control multiple elements. Some are not used until later in the guide. The CSS:
The padding and margins are both set to 0px. This ensures that the layout is right at the top and left edges of the browser window. The background added here creates the left background for the left column. The background is aligned left and repeats along the y axis (vertically).
A default font is set for all div elements.
The padding and margins are both set to 0px for all form elements.
A default format is set for all links. The links will be customized in groups or individually later.
We us br's to clear floated elements. However we don't want the default vertical spacing that br's have so the height and line-height are set to 0px. Don't worry if you don't understand what floated elements are! These excellent css float tutorials will bring you up to speed on how floating works.
In the header we have the top navigation and logo. The markup:
The CSS:
What's happening:
When working with CSS-P you will almost always have a single containing element that holds all the other elements in the page. Sometimes you will have more than one containing element. In this layout, there is a div (#header) that contains the top navigation and logo; the elements in the header. There is another div (#wrapper) that contains all the other elements. The reason the header elements are inside their own containing element is because the header background stretches all the way across the page. The #wrapper div does not stretch the entire width of the page. If we put the header elements inside, the background would be cut off on the right side.
The header's position property is set to relative. In CSS-P any element that is to be positioned is positioned in relation to its nearest positioned parent. We want to precisely position the top navigation and logo on the page so we position their parent, the header.
The background is set. We use the repeat-x value so that the background tiles all the way across the browser window.
Without a height value, the header collapses and other elements move up into the space.The elements inside the header are positioned absolutely. A height is set to prevent the header from collapsing. The used is the height of the background that tiles across the page. The height is set to this value so that the entire background is visible vertically. If the height were set to 170px instead of 180px, part of it would be cut off.
We need the top navigation to move down and to the right so that is sits on the background exactly where we want it. The position property is set to absolute.
When using the position property, you have three options for values:
The relative value takes the element you are positioning and moves it from where it was. The element is moved by the amount you specify with the top, left, right, and bottom properties. When elements are positioned relatively, the spaces they were in are still preserved.
The absolute value does works the same way as the relative value. The difference is that an absolutely positioned elements does not have the space it was in reserved. Absolutely positioned elements are completely removed from the document flow. Other elements may be obscured by those that are absolutely positioned.
The static value positions an element as it would normally be positioned. Since CSS properties cascade, you may end up with an element which has been incorrectly positioned relative or absolute. This is when you would use the static value. The element would be return to its' default position in the document flow.
Detailed positioning examples.
The top navigation needs to move down 10px and to the right 10px. The top and left properties are used to accomplish this.
The list-style-type property is set to none. This gets rid of the bullets that would normally show with an unordered list.
All list elements have margin and padding values by default. Setting the values to 0px removes the defaults.
The dividers between the navigation items are added using the background property. The top and right values are used to position the background to the top and right. The no-repeat value prevents the background from tiling across the width of each navigation item.
If the li elements aren't floated, they display one on top of the other.In a list, the li elements are block level elements. What this means is that they will stretch as far horizontally as they can. This is why li elements display one on top of the other. Each one is stretched as far as it can. When an element is floated, it moves are far as it can in the direction you specify in the float value. The li elements here are floated left. This makes them collapse to the width of the text inside.
A complete list of all block level HTML elements.
Without the 2px of padding the rollover obscures the divider.2px padding is added to each li element. When the top navigation links are rolled over, the dividers would be covered by the rollover image if there was no padding.
Anchors are inline elements. This means that other elements flow right around them unlike block elements which take up as much horizontal space as they can. You cannot use properties that affect height on an inline element. These include height, padding-top, and padding-bottom. We do want to be able to affect the height of the anchors so we set the display property to block.
A complete list of all inline HTML elements.
Now that they are block elements the nav items are all displaying one on top of the other. Just like we did for the li elements, the anchors are floated left. This makes them collapse to the width of the text inside.
We can now add some height. The height of the top navigation is 40px.
If you have one line of text or a single element, you can center it vertically by setting the line-height to the same height as the element. This will not work with multiple lines of text or multiple elements such as several images. A quick example of vertical centering using line-height.
The top and bottom padding values are set to 0px. The height property is already making the anchors as tall as they need to be. Adding padding would stretch them taller than necessary. There is 10px padding total on either side of each link, so why is only 8px specified? Remember on the li elements 2px was added to the right to keep the dividers visible on rollover. That 2px is subtracted from the 10px total of each anchor leaving us with 8px.
Remember that in CSS-P any properties that alter the width an element or its spacing do so in an additive manner. If you have a 200px wide box and add 25px padding to the right and left sides, the width of the box is now 250px wide. As you learn more about the box model this will make more sense.
The background for the rollover is added. The repeat-x value is used so that the background tiles across the entire width of each navigation item.
The logo is positioned absolutely so that it can be moved precisely.
The logo is moved 60px down and 40px right.
The CSS:
The only CSS we apply to this element sets its width. Div's are block elements so our content in #wrapper will automatically show beneath the header. All of the elements from this point on will be inside this containing element.
The left column contains the search box, left navigation and bookmark links. The CSS:
Here's what's happening:
With CSS-P you can have columns just like with tables. The left column is floated to the left. A width of 200px is set. Without a width set the column would collapse to the width of the text inside. For this layout there's a specific width we want so it's set.
The markup:
The CSS:
What's happening:
The top and repeat-x values are used to position the background at the top of the search box and make it tile horizontally.
If you measure the search box in the PSD you will note that the height of the search box is 60px. Remember that in CSS-P any padding you add will increase the width or height of the box. We want the text field to be positioned vertically in the center of #search so we assign 20px padding to the top and left sides of #search. This makes 20px padding-top + 40px height = 60px total height. When you know the height of the elements involved, you can use this method to center them vertically.
If you have a complex form it is best to just go ahead and lay it out using tables. Yes, tables do have their uses. Just make sure you use all the proper attributes for form accessibility. When you have a simple form like this it can easily be laid out with CSS. The text field is floated left. When you have elements of a similar height, floating them will make them line up. This is how we get #inputSearch and #btnSearch nice and straight.
A 10px margin is applied to the right side of #inputSearch so it will be spaced apart from #btnSearch.
A little padding is applied to the top and left side of #inputSearch. This places the text right in the middle vertically and a little away from the left edge. You may be thinking that you could just line-height for the vertical centering. That only works in input fields in IE unfortunately. The amount of padding you apply to center your text will depend on the font-size you have set for your text in #inputSearch.
The total width of the text field is 130px. We have 1px border-left + 1px border-right + 3px padding-left + 125px width = 130px total width. If you see things aren't lining up in your layout, always check to make sure you've accounted for any extra width added by things like borders and padding. 1 errant pixel of spacing really can drive you insane.
The total height of #inputSearch is 20px. We have 1px border-top + 1px border-bottom + 2px padding-top = 20px total height.
The markup:
The CSS:
What's happening:
The margin, padding, and list bullets are removed just as we did for the top navigation. A background image is applied that will serve as the last divider in the left navigation. For each li element the divider is positioned at the top. You can only have one background per element so we apply the last divider to the ul itself to cap off the bottom of the left nav. The background is positioned to the bottom and right and does not repeat.
The divider for each li is added. It's positioned to the top and right and does not repeat.
Remember that inline elements such as anchors cannot have their height altered so we set the display property to block so we can add height.
The total height of each menu item is 40px. However 2px of that height are taken up by the divider in each li element. We use the line-height property to center the link text vertically in each li. If you were thinking the line-height should be set to 40px, that is a good idea but this would cause the link text to be off vertically. Technically it would be centered but our available height excluding the 2px divider is only 38px so that value is used for the height and line-height.
2px of padding are added to the top of each li and 20px to the left. The 20px of left padding move the link text away from edge of the left column.
When a menu item is selected we want some kind of indication. The red text alone would be ok but the icon makes it even more obvious. For the left value 20px is used. This positions the background image (the icon) 20px from the edge of the left column. The center value is used to center the background vertically. The icon should not repeat so the no-repeat value is used.
Now that there's an icon there the link text for the selected menu item needs to be pushed farther than the regular links so 30px of padding is added to the left of the #level0Selected link.
Without additional padding the spacing is incorrect for the second level menu.In each top level menu item the height is set by the anchors. We'll do the same for the second level menu items. But we need to add 10px additional padding to the bottom of the second level ul so that the spacing is correct.
Remember that the C in CSS stands for cascading. We applied a background to our top level ul so the second level ul will have the same background. We don't want that so the background property is set to none to get rid of it.
The dividers that are set on the top level li's will cascade down to the second level. We don't want that so the background property is set to none.
The second level links each have a bullet. The background's left value is set to 40px to move the icon 40px from the edge of the menu.
The second level menu items are half the height of the top level menu items. There's no divider taking up height in each element so the height and line-height are both set to 20px.
We don't want any padding to cascade down from the top left so the padding values are set to 0px on all sides except the one we want to affect which is the left. 50px of padding are added to the left side to move the link text to the right of the icon.
The markup:
The CSS:
The bookmarks are spaced 20px from the bottom of the left navigation. Padding is applied to #bookmarks.
Padding, margins, and bullets are removed from the bookmarks the same way as for the top and left navigation.
Setting the display property to block makes the links stretch the width of the left column just like in the left navigation. This also allows height to be applied to each link.
We don't want the links on edge of the left column, so padding is applied to move them away.
The height and line-height are set to the same values to center the link text vertically.
Since each link will have a different icon, each one has its own ID. Now we can assign the icons. 20px is used for the left property so that the icon is moved away from the edge of the left column.
The right column contains 2 columns of it's on. Column 1 contains the main content. Column 2 contains the headlines, newsletter, and links. The CSS for the right column:
The total width of #wrapper is 960px. The left column is 200px wide. This leaves 760px for the right column. There is a 1px border on the right, bottom and left sides so 2px is subtracted from the available width leaving 758px for the right column.
The right column needs to be on the right side of the layout so it is floated right. You will note that your widths must add up exactly. If the width of the right column were set to 760px instead of 758px, it would display to the right and below the left column. This is because there wouldn't be enough room for both to fit.
The hr element has borders on all 4 sides. The top border is set to the color we want. The left and right borders are set to none. The bottom border is set to the color of the background. In most browsers you can set the bottom border to none as well. However this does not work in IE.
The CSS:
#col1 contains the main content. #col1 is floated left so that it displays on the left side of the #rightCol.
The total width of #col1 is 500px. Since there is 20px padding on all sides the padding must be subtracted from the total width. 500px total width - 20px padding-right - 20px padding-left = 460px width.
This is a big block of code, but most of the elements are duplicated across the three sample items. The markup:
The CSS:
There's a border at the bottom of each item. 20px of padding is adding to create some space between the info bar and the border. A 20px margin is added to the bottom of each item to create space between the bottom of one item and the top of the next.
Heading elements have a pretty big margin on both the top and bottom. The p tags in the content have not had their margins altered so they will serve to space the headings from the content.
The heading for the featured item is styled differently so that it will stand out. Headings are block elements so padding can be applied to them. Padding and a background color are added.
We use the text-align property to make the contents of the info bar align to the right side. Why not use float? Floating the info bar right would make the entire red bar collapse to the right side of column 1 and this isn't what we want.
The item image div is floated left. It has collapsed as far right as it can.
Without any margin values added the text would be in contact with the image. 10px margins are added to the bottom and left sides of the item image to prevent this.
The text-align property is set to center so that the image caption is centered underneath the image.
10px padding is applied to create some space bettween the image and the border we're setting next.
5px margin is added to the image to create some space between it and the caption. A simple 1px border is added.
You may have noticed that item 3 has two classes: .item and .lastItem. For item 3 we don't want a border or extra padding and margins so they are removed. This makes everything look nice and finished for item 3.
The CSS:
The total width of column 2 is 260px. The widths of all the other elements have to be considered when setting the width property. The total width #wrapper is 960px. 960px total width - 200px left column width - 500px column 1 width - 2px border around #rightCol - 20px padding-left on column 2 - 20px padding-right on column 2 = 218px width for column 2. This column needs to be on the right side so it's floated right. The .titleLarge style is used for headings in the right column.
The markup:
The CSS:
Each block of headlines has an image to go with it. The image is floated left. A 10px margin is added to the right side to move the links away from it. The image by default displays above the height of the links so a 3px margin is added to its top to move it down.
A 10px margin is added to the bottom of each headlines block to space them apart.
The bullets, padding and margin are removed.
After each ul a >br clear="all& /< is added. In CSS-P floated elements are removed from the document flow. The floated image extends below the links. Without the >br< each headlines block would be in contact with the one below. >br clear="all& /< is added after the #headlines div for the same reason.
A >hr< is added to provide a visual separation between the headlines and newsletter.
The markup:
The CSS:
10px padding is added to the bottom of the #newsletter div to space #inputNewsletter and #btnNewsletter away from the <hr>.
A 20px margin is added to the bottom of #newsletter p to space it away from the text field and button. No margin or padding on top is necessary because the title has a margin applied that is keeping it spaced from the text content.
#inputNewsletter is styled very much the same way as #searchInput. We just have to be sure to add up all the borders and padding used to make sure the width is correct. Both #inputNewsletter and #btnNewsletter are floated left to make them line up.
A >hr< is added to provide a visual separation between the newsletter and links.
The markup:
The CSS:
All bullets, margins and padding are removed.
A 3px margin is added to each li to space the links apart. The links in the links section are just regular links that do not span the width of #col2. Since we didn't make them block elements we can't add margins to them so the margins are added to the li's instead.
The background property is used to add a bullet to each link. 10px padding is added to the left of each link to move them away from the edge of #col2 so that they don't obscure the bullets.
The markup:
The CSS:
The #footer div spans the entire width of #rightCol. The total width of #rightCol is 760px. There is 20px of padding on all sides of the #footer div so that amount is subtracted from the total width. 760px #rightCol width - 20px padding-right on #footer - 20px padding-left on #footer = 720px. A 40px margin is added to the bottom of #footer to space it away from the bottom edge of the browser.
The text-align property is used to horizontally center the contents of the footer.
All bullets, padding and margins are removed from the footer navigation. The display property is set to inline to make the links display horizontally instead of one on top of the other. The links here could be floated, but floated elements cannot be centered using the text-align property. To space the links apart horizontally, 20px of padding is added to the left and right of each link.
The default margins are removed from the p element. Padding is added to space #copyright away from #footer ul and to make the text wrap to two lines.
If you've made it this far and read everything congratulations. There are many ways to accomplish any given task and you can do a lot of cool things with CSS-P. Never stop reading, and never stop learning...