4.1.2. Absolute Versus Relative Positioning
The position attribute
terminology can be confusing because the coordinate system used to
place an element depends on the positioning
context of the element, rather than on a universally
absolute or relative coordinate system. A positioning context is
nothing more than a rectangular space with edges that become zero
reference points for specifying a location within the rectangle. The
most basic positioning context is an invisible box created by the
root document node. In early CSS-P browsers, this
box equated to the body element
container.[4] But today (under the influence of the DOM node tree
architecture), the document is the most global context. If the
document were a sheet of paper, the 0,0 point would be at the very
top, left corner of the page. In other words, the entire (scrollable,
if necessary) space of the browser window or frame that displays the
content of the document is the default positioning context. The 0,0
coordinate point for the default positioning context is the upper
left corner of the unscrolled window or frame. You can position an
element within this context by setting the position attribute to
absolute and assigning values to the
left and top attributes of the
style rule:
<div id="someDiv" style="position:absolute; left:100px; top:50px">
Hello. And now it's time to say goodbye.
</div>
Figure 4-1 shows how this simple block-level
element appears in a browser window.
Figure 4-1. An element positioned within the default positioning context
Each time an element is positioned, it spawns its own, new
positioning context with the 0,0 position located at the top left
corner of that element. Therefore, if we insert a positioned element
in the previous example nested within the div
element that forms the new positioning context, the newly inserted
element lives in the new context. In the following example, we insert
a span element inside the div
element. Positioning attributes for the span
element place it 10 pixels in from the left and 30 pixels down from
the top of its positioning context—the div
element in this case:
<div id="someDiv" style="position:absolute; left:100px; top:50px">
Hello.
<span id="someSpan" style="position:absolute; left:10px; top:30px">
Hello, again.
</span>
And now it's time to say goodbye.
</div>
Figure 4-2 shows the
results; note how the div
element's positioning context governs the
span element's location on the
page.
Figure 4-2. A second element nested inside another
Notice in the code listing that the
position attribute for each element is
absolute, even though you might say that the
nested span element is positioned relative to its
parent element. Now you see why the terminology gets confusing. The
absolute positioning of the span element removes
that element from the document's content flow
entirely. The split content of the parent div
element closes up, as if the content of the span
element wasn't there. But the
span element is in the document—in its own
plane and shifted into a position within the div
element's positioning context. All other
parent-child relationships of the div and
span elements remain intact (style sheet rule
inheritance, for instance), but physically on the page, the two
elements appear to be disconnected.
The true meaning of relative
positioning can be difficult to visualize because experiments with
the combination of absolute and relative positioning often yield
bewildering results. Whereas an absolute-positioned element adopts
the positioning context of the next outermost context, a
relative-positioned element creates its own positioning context with
respect to the element's normal (unpositioned)
location within the document's content flow. A
sequence of modifications to some content should help demonstrate
these concepts.
To begin, here is a fragment with a single, absolute-positioned
div element that contains three sentences:
<div id="someDiv" style="position:absolute; left:100px; top:50px">
Hello.
Hello, again.
And now it's time to say goodbye.
</div>
This code generates a simple line of text on the page, as shown in
Figure 4-3.
Figure 4-3. A simple three-sentence DIV element
Pay
special attention to the location of the middle sentence as it flows
in normal HTML. Now, if you turn that middle sentence into a
relative-positioned span element supplied with
some offset (left and top) values, something quite unusual happens on
the screen. The following fragment positions the second sentence 10
pixels in from the left and 30 pixels down from the top of some
positioning context:
<div id="someDiv" style="position:absolute; left:100px; top:50px; right:100px">
Hello.
<span id="someSpan" style="position:relative; left:10px; top:30px">
Hello, again.
</span>
And now it's time to say goodbye.
</div>
But
what is that context? With a relative-positioned element, the anchor
point of its positioning context is the top left corner of the place
(the box) where the normal flow of the content would go. Therefore,
by setting the left and top
attributes of a relative-positioned element, as in the previous code
fragment, you instruct the browser to offset the content relative to
its normal location. You can see the results in Figure 4-4.
Figure 4-4. The relative-positioned element generates its own positioning context
Note how the
middle sentence is shifted within the context of its normal flow
location. The positioning context established by the
relative-positioned element is now available for positioning of other
elements (most likely as absolute-positioned elements) that you may
wish to insert within the <span> tag pair.
Take special notice in Figure 4-4 that the browser
does not close up the space normally occupied by the
span element's content because it
is a relative-positioned element; if it is absolute-positioned, the
element gets yanked from its parent's rendering, and
placed into its own layer. Since the element is no longer in the same
block as its parent, the surrounding parent text closes the gap.
In
most cases, you don't assign values for
left and top to a
relative-positioned element because you want to use a
relative-positioned element to create a positioning context for more
deeply nested elements that are absolutely positioned within that
context. Using this technique, regular content flows according to the
browser window's current size or as its appearance
is affected by style rules, while elements that must be positioned
relative to some running content are always positioned properly.
To demonstrate this concept, consider the following fragment that
produces a long string of one-word sentences plus one longer
sentence. The goal is to have the final sentence always appear
aligned with the final period of the last
"Hello" and 20 pixels down. This
means that the final sentence needs to be positioned within a context
created for the final period of the last
"Hello." In other words, the period
character must be defined as a relative-positioned element, so that
the nested span element can be positioned
absolutely with respect to the period. The following code shows how
it's done:
<div id="someDiv" style="position:absolute; left:100px; top:50px; right:100px">
Hello. Hello.
Hello. Hello. Hello. Hello. Hello. Hello. Hello. Hello. Hello. Hello. Hello.
Hello. Hello. Hello<span id="someSpan" style="position:relative">.
<span id="anotherSpan" style="position:absolute; top:20px; width:80px">
And now it's time to say goodbye.
</span>
</span>
</div>
Carefully observe the nesting of the
elements in the previous example. Figure 4-5 shows
the results.
Figure 4-5. A relative-positioned element creates a positioning context for another element
If you resize the browser window so that the final
"Hello" appears on another line or
in another vertical position on the page, the final sentence moves so
that it always starts 20 pixels below and just to the right of the
period of the final "Hello" of the
content. When applied in this fashion, the term
"relative positioning" makes
perfect sense.