Simple CSS templates
The most frequent question in the #CSS channel I'm in is about how you make a 2 column layout. Most beginners seems to have problems understanding how floats work since they are quite different from tables. So I sat down and made some simple layout templates for you. These layouts will all be made with floats since that's the easiest way to do things. I could have set out to use absolute positioning but that can get tricky when it comes to placing the footer. Let's stay with floats.
I'll recap how a floats work. A float is applied by simply setting float: left
or float: right
on an element in your CSS-file. The element then gets pushed as far to the left or right as possible and the next element will follow to the right (if floated left) or left (if floated right). The closest HTML comparision is the effect you get when setting align="left" on an image. In the beginning it helped me to think of floats like that.
There are basically two ways to make 2 column layouts with floats. Either you float all the columns (float-float) or you float all but the last one (float-margin). The former method makes it easier to work with clearing inside of the second columns though, so if you're going for a complex layout float-float might be better. The latter has the advantage that you don't have to set a width on the last column. It will fill whatever space is availiable. My favourite is still float-margin though, the automatically expanding second column makes sure the the full width is used no matter what.
For the examples below I will use the HTML I outlined in my previous article about CSS basics.
The float-margin method#
Let's start by looking at some examples:
Ok, so how does this work? The first example: The navigation is floated left which means that the next element will follow to the right of it. This sounds right but we are forgetting one thing, what happens if the navigation is very short? Then the text in the right column will continue below the float, probably not what we wanted. So, to fix this we add a margin-left to our content division. Voilà!
The 3 column example is based on the same idea. Here we start by floating the navigation left, floating the first content block right and finally add margins to the second content block. The last block needs to have both a margin-left and a margin-right to stop the text from continuing below the left and right columns. Makes sense? Take a look at the code and I hope it will.
The float-float method#
Another method of doing the same is floating each of the columns left. This means that the columns will show up on the webpage in the same order as you put them in the HTML (that was not the case in the previous example, content1 was to the right and content2 in the middle). Some examples for you:
There isn't much explaination needed here, only thing different from the float-margin method is that you need to set a width on all your columns. You should easily be able to expand this method to kazillion columns :)
That's all, be sure to poke around with the different layouts to get a feel of how they work for you. In my next post I will go through some less static layouts, namely elastic and fluid layout. Comments are availiable for questions.
Update: Added an article on Common questions beginners ask
Comments
By: Thomas Sydorowski (#1)
By: Velaluka (#2)
a suggestion: always add the browsers you tested your code for.
u know: IE 5+, Moz FF 1.x etc
By: Emil Stenström (#3)
@Velaluke: Good suggestion. I generally code for IE 6, FF 1.5 and Opera 8.5 and test in all those browsers. So that's what I mean. The layouts to the right work in those browsers too. Thanks for commenting.
By: simon (#4)
I'm using Konqueror now but usually use Opera (by choice) and FireFox - but have to develop for IE6.
:
I use tables generated by a program and separate pages for printing using (between tables) with the body background set to grey - this shows the paging the user will get when printed.
(div {page-break-after:always} )
How can I change this to floated columns (cells really)- or should I stay with tables ?
By: Emil Stenström (#5)
I'm not sure I understand your other problem... but you should never use tables for layout, it's not worth it.
By: Inge (#6)
Thanks a lot.
By: SiN (#7)
By: Ben (#8)
Thanks for putting your ideas out for everyone to see. I really like your clear, straightforward manner of presenting the key ideas. Also - your code formatting is crisp and clean too, making it that much easier to understand and maintain. Do you do this manually (not a big deal for your small sample sites - but can be an issue for larger sites)? If not - can you share with us what editor/development tools you use? Thanks!
By: Emil Stenström (#9)
@Ben: I have done a couple of larger sites too and CSS is just fine to use there too. On larger sites you might want to a one global, one module specific and even one page specific stylesheet. That makes the site very flexible in design. I use an editor called TopStyle for my CSS editing, it's availiable as a "Lite version" for free.
By: Ern (#10)
Great site!!!! Very clear and easy to understand
regards
Ern
By: Simon (#11)
Thank you. This is what I have been looking for. Great
instructions.
Simon
By: Jason (#12)
Sorry for the long comments that considerably stretched this left div:)
Regards.
By: Jason (#13)
By: Emil Stenström (#14)
To accomodate different resultions I usually do like on this site, use a width that is set in the "em" unit. I try to make the dafult size work in 800x600 (I know that's not true for this site) and then let people with higher resolutions use the text-zoom. Percents works too but then you need to take care to not make your lines too long, that has readability implications.
The mouseover effect changes color, background-color and border on the link. It's simply done with:
a:hover { color: white; background: grey; border: 2px solid red; }
Thanks for dropping by.
By: Jason (#15)
By: Jason (#16)
By: Jason (#17)
Another (probably) silly question by me: on the 3column f-m method you use id=header in the body but you haven't got any declarations for "header" in the CSS - does that mean that it understands what "header" is? What if you want to remove the border from the header i.e. when you want to have an image logo occupying say 780px of width? Also by not using the "" at the begining of the page does it have any implications on XML - the feed maybe? If I include that line, the design you have for f-m 3-col, just breaks in IE... Sorry if my comments were silly; it is just I was still unclear about a few things.
By: Emil Stenström (#18)
Adding "header" is just a way for me to give the div some kind of label and make it easy to use from your CSS. You can just set
#header { border: none; }
if you want to remove the border from the header.By: gta_rules (#19)
Great job... simple and powerfull...
By: css-learner :) (#20)
By: Nic (#21)
can you pleas direct me to a good extensive tutorial on HTML, the new HTMl 4.01 or XHTML so i can learn proper coding? I know a bit already but i would like to have an extensive knowledge in it so I can know as much as possible about coding HTML/XHTML?
Thank you very much
By: Emil Stenström (#22)
By: Brian (#23)
HR
{
color:#F78400;
size:4
}
to the CSS, and inserted in my HTML file, the color was set properly, but not the size. Is there a way to set the size. Is there a good on-line reference for what properties of tags can be reset in CSS?
By: frank (#24)
By: Levi (#25)
By: Emil Stenström (#26)
The problem with 100% you mention is often caused by small things like borders. According to CSS the real width of an element is the width you have set plus margins, borders, and paddings. So if you set a width of 100% and a border of 1px your layout may break. There's also a bug in IEs way of calculating widths that makes IE even worse to work with and the solution to that is to simply use the float-margin method. That way you only need to set the width of one of the columns and it doesn't really matter exactly how wide the other one is, it at least won't drop down.
By: Levi (#27)
By: Carl (#28)
Carl
By: Emil Stenström (#29)
@Carl: Thanks. Good you like it.
By: Aaron (#30)
thank you
By: Mis Algoritmos » Blog Archive » Plantillas CSS (#31)
By: Kapil Kanojia (#32)
By: miro (#33)
By: Emil Stenström (#34)
By: PHPKB Knowledge Base Software (#35)
By: Larry (#36)
By: Emil Stenström (#37)
Hope that gives you some ideas.
By: ITVGuy2000 (#38)
I wish I had found this resource two years ago.
Just quick suggestion tho. It might be useful to include the year when you present dates.
By: Harshad (#39)
By: Mary (#40)
http://i68.photobucket.com/albums/i36/edvy/css01.jpg
You'd be my hero if you help me.
Thank you in advance!
By: Emil Stenström (#41)
By: Wretched and Beautiful : links for 2009-03-16 (#42)
By: Plantillas css básicas | Emilio José Rodríguez García (#43)
By: Shaon (#44)
By: David (#45)
I detest the decision to deny us the full usefulness of tables. Row height has been rendered useless, and this was a staple of many wonderful layouts. There was *no* real disadvantage, in the *real world*, to using tables.
As for using FLOATS for layout, that is *plagued* with problems. Try using a "clear:both" in any part of your body content, or menu content, and your template is destroyed. That's because "clear" clears *all floats on the page* not just the last one encountered.
Using floats for templates is nicely conformist, but highly impractical unless you are very careful with page content so it doesn't break the layout. That makes it a pain for CMS applications for a start.
The W3C is living in lala land when it comes to the needs of both designers and web app coders. If they just hadn't deprecated table row height it wouldn't be so bad. The fact they're now formalising the "border-box" option in CSS3 means many, many people have complained! IE did have a valid position, no matter what the purists say.
/rant
By: David (#46)
In the example given on this page, "3 columns using float-margin", add the following code to the "content2" block (replace square brackets of course):
[div style="float:left"]float this left[/div]
[div style="clear:both"][/div]
[div]template is now broken[/div]
When you add the above code, the "broken" words are placed below the level of the "content1" block. It is no longer flowing directly under the content2 text.
This is a problem where the "clear" appears in a column which is not as tall as one of the others. The text suddenly jumps to the lowest position on the page.
Therefore, using floats for layouts is ONLY practical if you NEVER need to use "clear:both" in your content.
By: Emil Stenström (#47)
If you want to use float-margin, you can still use clearfix to clear your content. So the templates are all fine, and we need no tables for layout.
By: Think Hive Studio (#48)
Just wanted to say thanks!
By: websitedevelopmentdeveloper (#49)