Topic: CSS - Relatively Absolute
Web design usually means something more than just fonts, colours and graphical elements. It also implies some sort of layout. A web designer has three available tools for creating a layout:
Layout tables belong in the last millennium. Floats are often the best solution, especially when you don't know in advance which column will be the longest. Older browsers, and Internet Explorer, aren't too good at dealing with floats, though. Besides, that's a separate topic.
Positioning is perhaps one of the most misunderstood parts of CSS 2. Let us look a little closer at how it works.
Absolute positioning is sometimes referred to as CSS-P. Beginners using Dreamweaver tend to call it layers, which is unfortunate, because it can be confused with Netscape's proprietary <layer> element.
But let's start from the beginning. The position property in CSS accepts four different values (plus inherit):
For all values except static we can affect the element's position through the top, bottom, left and right properties.
Elements with position:static, which is the default value for all elements, are not positioned at all. Their placement on the canvas is determined by where they occur in the document.
Thus the static value is only used for overriding a previously set value.
We will use the term statically positioned in this article, even though it isn't fully correct.
Elements with position:relative are positioned relative to themselves. This may sound strange, but it can be useful sometimes.
If we specify a value for either of the four edge properties, the relatively positioned element is shifted in relation to the position it would have occupied if it had been statically positioned.
This may sound like Greek to you, but it's actually quite logical. If we just set position:relative on an element, without specifying any of the edge properties, the element ends up exactly where it would have been if we had set position:static, or if we hadn't set position at all.
If we set top:10px, the element is shifted 10 pixels from its original top edge. That means it moves downward. A negative value shifts the element in the opposite direction, so we could achieve the exact same result by setting bottom:-10px. This means it's not meaningful to specify both top and bottom, or both left and right. There may, however, be reasons for specifying, for instance, top and left together, if we want to shift an element both vertically and horizontally.
Now, this isn't very useful for creating columns, because a relatively positioned element remains in the document flow ? in the position where it originally was. It still takes up space, but not where it's actually shown, but where it would have been shown, had it been statically positioned.
What does this mean in the real world? Relative positioning is mostly useful for shifting an element a few pixels in either direction, or you'll get a hole in your page. There is, however, another use for it that is much more important: A relatively positioned element counts as positioned, even if we don't shift it a single pixel in any direction. We will soon see why that is important.
What people normally mean by positioning, CSS-P or layers, is elements with position:absolute. The top, bottom, left and right properties specify the distance to the corresponding edge of the element. But from what?
Ironically, absolute positioning is relative. Yes, you read that right. An absolutely positioned element is positioned relative to another element, called the containing block. Here comes the definition of that. Take a few deep breaths and hold on tight to the armrests of your chair.
The containing block of an absolutely positioned element is its nearest positioned ancestor, or, if there is no such element, the document's initial containing block.
By positioned ancestor we mean a structurally superior element whose position property is absolute, fixed or relative. So here is that important use for relatively positioned elements that we touched on a minute ago. By setting position:relative for an element, without shifting it at all, we can establish a new context for its absolutely positioned children. Sounds easy, doesn't it?
But if there is no positioned ancestor then? That's where the so-called initial containing block comes into the picture. The CSS standard helpfully says that this is chosen by the user agent. (User agent is the application that processes a web page, for instance a browser, some assistive technology, or a search engine.) The standard also states that it could be related to the viewport. In practice this means either of the BODY or HTML elements.
Absolutely positioned elements are completely removed from the document flow. This means they don't take up any space. Or, to phrase it differently, they don't affect subsequent elements. We thus have to make sure ourselves that no other content ends up underneath our positioned element, unless that is the very effect we're after, of course.
An absolutely positioned element with top:100px is consequently placed so that its top edge is 100 pixels from the top edge of its containing block. In browsers that support CSS you can specify all four edges and let the browser compute the width and the height. Unfortunately this doesn't work in Internet Explorer, so it's almost always necessary to specify at least the width of an absolutely positioned element.
It is perfectly legal to specify negative values for the edge properties, but if you do, you should be very aware of what the containing block is. Otherwise you risk putting the element completely or partially off the screen.
We established earlier that absolute positioning is relative, so it should come as no surprise that fixed positioning is absolute.
An element with position:fixed is positioned absolutely with respect to the viewport (the browser window). Fixed positioning is very similar to absolute positioning, but there are differences. The position is always computed with respect to the viewport; the viewport is always the containing block. The element is removed from the document flow and it stays put even if the user scrolls the document.
Unfortunately Internet Explorer doesn't support fixed positioning. There are a number of more or less complicated ways to circumvent that, but fixed positioning isn't actually as useful as one may think. Sure, it's conceivable to have a menu in the left or right column that is always visible, but most users today expect everything on the page to move upwards when they scroll.
Absolute positioning is useful for multi-column layouts, as long as you always know which column is longest. Since the absolutely positioned elements are removed from the document flow, the don't affect subsequent elements. Therefore it is very difficult to have a full-width footer appear after all the columns.
As with any web design, you should try to use relative units with positioning, so that the layout can adapt to different window sizes. The value for left, for instance, should be specified in em or %, not in px.
If you specify the width for an absolutely positioned element, either explicitly via width in percents, or implicitly via left and right, the standard says that it should be computed relative to the containing block. Both Internet Explorer and Opera get this wrong, unfortunately, and use the width of the parent element as the basis for their computations. Gecko-based browsers like Mozilla and Firefox behave correctly.
With all types of positioning, including relative, you should set margins and padding explicitly, especially if you want it to look the same cross-browser. Browsers have different standard values for these properties.
When positioned elements overlap, we can control the stacking order with the z-index property. The higher the z-index, the closer to the user the element ends up. Unfortunately this isn't quite as straightforward as it sounds, since each containing block establishes its own context for z-index. So to put one element on top of another element, with a different containing block, you need to increase the z-index for the first element's containing block. In really complex layouts you can find yourself in impossible situations, if you want to stack three elements where the middle one has a different containing block than the other two. As far as we know, this cannot be done.
Absolute positioning is often used with DIV elements, but it's perfectly valid to position any element.