Main column
This box hasn't been positioned - it is still a statically-placed element in the flow of the HTML document. The CSS for this block (which has been given the id “main” is:
#main {
margin-left: 275px; margin-right: 25px;
padding: 5px;
border: 1px solid black;
}
Setting the margin in this way ensures that the main column never
overlaps the side panel. The same can also be acheived by using absolute
positioning on both items. However, positioned items are lifted out of the
normal document flow, so the advantage of leaving #main as a static
item is that you can place text and other elements after it. What that
really means is that, if both boxes on this page were positioned using
“position: absolute”, then <body>
would end just after the title ("Positioning") - both columns would overflow
it.
Units
This example uses pixels, but there are several other units that can be
used. If your stylesheet is for printing, then pixels aren't recommended.
You can also use ems (unit: em), percent of the containing block
(so in this case, the width or height of <body>,
whichever is appropriate) whose unit is the % sign, even traditional
units such as points (unit: pt. There are 72 points per inch), centimeters
(unit: cm), etc. etc.
Using percentages may surprise you every now and then. If you specify a
width of 100% of the browser window, note that this is the full width, and
by default the <body> element has margins and/or padding
around the inside. Set them both to 0px unless you want to see
scroll-bars.
As a general rule, do not mix units when positioning items, you'll end up tearing your hair out in frustration when boxes start overlapping, or showing up in unexpected places. The best general purpose units are pixels, percent and ems. And despite the warning, don't be too rigid — now you know the rules, you should know when you can afford to bend or break them.
Oddities
An often-surprising thing about absolute positioning is the point of
reference. If you put an absolutely-positioned
<div> inside another, then the position of the inside
block will be relative to the position of the outside block, not the
browser window. This is very useful indeed, but only if you're expecting
it. Defining an absolutely-positioned block inside a statically-placed block
(like this column is right now) is different - the block is lifted out of
the static block and positioned relative to the <body>
tag. This happens whatever unit you use, but percentages are much more
obvious about it because they're a relative unit. You would probably benefit
from a picture here, but I'm lazy.
You might think that (from the rules given here), there should be 25 pixels between the side panel and the main column. This is a common mistake (which is why it hasn't been corrected here): browsers in standards-compliance mode take the width of a block, then add the padding and border. This means that #menu isn't in fact 225 pixels wide, but 237 pixels, because of the 5 pixels of padding on either side and the 2 pixels (total) of black border.
If you fail to include a valid HTML 4 or XHTML doctype line at the start of your document, IE 6, Safari, Opera and Mozilla-based browsers (including Netscape 6 onward) will use a "quirks mode" in which the given width includes the padding (so the menu will be 225 pixels wide after all). There are several other differences in quirks mode, not all of them desirable (and certainly not consistent across browsers), so (IE 5 aside), it's best to use standards mode wherever possible..
The more astute of you will wonder, “What about IE 5?”
The answer is that IE 5 has no standards compliance mode; it is the quirky
browser for which all these other browsers have included a quirks mode
(well, that and Netscape 4). If you are designing to include IE 5 users,
there are three things you can do:
- Allow for differences in box size
Be flexible and leave room for IE 5's mistake. What's a few pixels between friends?
- Do not specify padding on the block
Instead, put margins on all the blocks that appear inside that block by using a "descendent selector":
#menu { position: absolute; top: 80px; left: 25px; width: 225px; border: 1px solid black; } #menu p, #menu dl { margin: 5px; }This will put 5 pixels spacing around paragraph tags and definition lists (<dl>..</dl>)inside the menu panel (the rule doesn't apply elsewhere). Other block elements usually already have margins - particularly lists
- Use a CSS hack
IE 5 has glitches in the way it reads CSS files. It's possible to exploit one of those glitches to hide a section of CSS from IE 5, while other browsers see all of the code. For example:
#menu { position: absolute; top: 80px; left: 25px; border: 1px solid black; padding: 5px; width: 225px; voice-family: "\"}\""; voice-family: inherit; width: 213px; }Every browser will read the width as 225 pixels, then as 213 pixels, except for IE 5, which chokes on the voice-family rule we rigged to catch it. Using CSS hacks is ugly, but is a less evil than performing browser detection. If you require a pixel-perfect layout, you may find you have no choice.