To a browser, everything is a rectangle. As you layout a web-page, think in terms of a piece of graph paper. Each square on the graph paper can represent a pixel. There are no half-pixels or round pixels or curved pixels. All a browser can do is draw rectangles. These rectangles, though, can be placed "next to" each other (or, one after the other), or nested within each other, or even overlap.
CSS allows you to control the placement of elements using the "position" property. There are four possible values: position: static; position: fixed; position: absolute; position: relative;
Don't assume you know what those mean. These values are not what I consider intuitive. I cost myself a lot of frustration assuming, for example, that "absolute" really meant, well, "absolute". It doesn't. And "relative"? Relative to what? What follows, then, is a description of what each of these values actually mean.
This is the default value. If you don't assign a position property to a styled element, it acts as if you assigned position: static. This means that the element will be placed in it's "natural" spot within the flow of the document. Now, I can't really explain what the "natural" spot is, without explaining the CSS Box Model, which I'll do in a future article. Most of the time, "static" means "right where you expect it to be".
An element that is "fixed" isn't supposed to scroll. That's as close as I can come to understanding "fixed". The W3C says "fixed" is a type of "absolute". That doesn't really clear things up for me. Through experimentation, I created a page that looked like what I expected in FireFox/Mozilla, but I could never make sense out of what Internet Explorer was doing with "fixed" elements. So my advice? Avoid "fixed" positioning.
An element that is absolutely positioned requires a "top" and a "left" property (although specifying a "right" property instead of a left works in FireFox and IE):
.myStyle
{
position: absolute;
top: 0px;
left: 0px;
}
However, these coordinates are not truly absolute. Here's one of those explanations you'll need to read twice: the top/left coordinates are calculated respective to the nearest absolutely positioned parent container. The content of that container is ignored, meaning that an absolutely positioned element can sit on top of the content of other containers. "Nearest" refers to the nesting hierarchy. If you have an element within an element within an element, it's helpful to think in terms of "grandparent, parent, child". If all elements are absolutely positioned, the "child" element will be positioned respective to the "parent" element's position.
Consider the following simple web page:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html>
<head>
<style type="text/css">
.outer
{ position: absolute;
top: 20px;
left: 20px;
background: #ff0;
margin: 0 auto;
padding: 0;
}
.inner
{ position: absolute;
top: 0px;
left: 0px;
background: #f00;
margin: 0 auto;
padding: 0;
}
p
{ margin: 0 auto;
padding: 0;
}
</style>
</head>
<body>
<div class="outer">
<p>Content of outer div.</p>
<div class="inner">
<p>Content of inner div.</p>
</div>
</div>
</body>
</html>
Example 1.
The inner div sits on top of the "outer" div. This is because both div containers are absolutely positioned. The inner div is positioned at 0,0, relative to it's parent, the outer div.
If we remove the absolute positioning from the outer div, it no longer is considered the parent of the inner div. (Huh? Go reread that explanation I told you to read twice.) So now the inner div considers the document (or "body" tag) its parent, and positions 0,0 relative to the entire document.
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html>
<head>
<style type="text/css">
.outer
{ position: static;
top: 20px;
left: 20px;
background: #ff0;
margin: 0 auto;
padding: 0;
}
.inner
{ position: absolute;
top: 0px;
left: 0px;
background: #f00;
margin: 0 auto;
padding: 0;
}
p
{ margin: 0 auto;
padding: 0;
}
</style>
</head>
<body>
<div class="outer">
<p>Content of outer div.</p>
<div class="inner">
<p>Content of inner div.</p>
</div>
</div>
</body>
</html>
Example 2.
Elements that are positioned with "relative", respect the content of their parent container. In this respect, they are like items with "position: static", in that they are first placed within the normal, natural flow of the document, and then futher offset relative to that placement, by the values of "top" and "left".
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html>
<head>
<style type="text/css">
.outer
{ position: absolute;
top: 20px;
left: 20px;
background: #ff0;
margin: 0 auto;
padding: 0;
}
.inner
{ position: relative;
top: 0px;
left: 10px;
background: #f00;
margin: 0 auto;
padding: 0;
}
p
{ margin: 0 auto;
padding: 0;
}
</style>
</head>
<body>
<div class="outer">
<p>Content of outer div.</p>
<div class="inner">
<p>Content of inner div.</p>
</div>
</div>
</body>
</html>
Example 3.
The red inner div is inset 10 pixels because of the "left: 10px". But notice that, even though the top property is set to 0, it is 0 relative to the content of the yellow outer div. The coordinates are offsets from the "natural" position of the element.
We've been using positive numbers for our coordinates in all of these examples. However, negative numbers are perfectly valid. I encourage readers to copy the source code examples in this article, and experiment liberally with CSS Positioning.
Thomas D. Greer has years of experience in the printing business. He held the position of Director of Development for Consolidated Graphics, where he wrote the COIN eCommerce platform. Prior to that he was Vice-President of Technology of a large printing company acquired by Consolidated Graphics, where he was responsible for the development of a completely custom-written plant management system still in use.
Today Thomas provides consulting, development, implementation, and training services to commercial printers. He can be reached on the web at www.tgreer.com.
Perhaps you'd like to read some other technical articles I've written?
If you'd like to discuss this article, or make suggestions for future articles, join my free discussion forum.
My logo was designed by Rus Anderson, a skilled graphic artist with a wealth of experience in user interface and web design. I told Rus I wanted something simple and clean, that conveyed my expertise in document automation technologies. I also wanted an association with PostScript and PDF. I'm very pleased with the result. The "document icon" has become ubiquitous. It's obvious, when viewing the logo, that I'm involved in document production and automation. The red color is associated with Adobe, PostScript, and PDF. Overall, the effect is clean and memorable. Thanks, Rus!