COM271, Week 5
Static, relative, and absolute positioning
Syllabus | Table of Pages | Assignments | References and Useful Links
In html, page layout results from normal flow of page elements, floating, and extensive use of tables to keep things squared off. With the attribute position and its collaborators top, bottom, left, and right, CSS liberates a developer from html structure, giving a high degree of control over placement of page content.
Position: The CSS attribute position assigns a method for placement of elements. The value static is the default, meaning an element will be positioned through normal page flow.
{position:static;}
The following values for position remove the element from the normal flow and reposition it as determined by offset attributes top, bottom, left, and right. Values for position are:
- absolute—element is removed from page and relocated relative to the page as determined by offset attributes; space formerly occupied by the element is freed for use by the normal flow of the remaining page content.
{position:absolute;} - relative—element is removed from page and relocated relative to the page as determined by offset attributes; space formerly occupied is preserved and page elements to not flow into it
{position:relative;} - fixed—element is removed from page and positioned relative to the screen,
as determined by offset attributes; space formerly occupied by the element is freed for use by the normal flow of the remaining page content.
{position:fixed;}
(These two examples do not appear on the print version of this page, for obvious reasons.)
Example of absolute positioning: The column to the left (W3C Schools CSS Reference Quick Index) is id'd as "left_col" and styled with these rules:
#left_col{width:150px;position:absolute;top:15px;left:10px;border:1px solid #ccc;padding:3px;}
Notice that as you scroll the page, the column maintains its place on the scrolling page.
Example of fixed positioning: I have duplicated the W3C Schools column on the right. It has an id="right_col". It is styled identically to "left_col" except for positioning:
#right_col{position:fixed;top:250px;left:1000px;}
Notice that as you scroll the page, the column maintains its place on the screen. Notice also that because the positioning is too far from the top of the screen, it is impossible for a user to see the bottom of the element, which extends beyond the bottom area of the screen. Oops!
Remember that fixed positioned navigation such as in this example may appear fine on your monitor at your resolution, but design with lower resolutions and smaller monitors in mind: will your page user be able to see the last lines of your navigation? If you have any doubts, relocate (e.g., transpose a vertical column of links into a horizontal row across the top of the page) or use absolute (page-relative) positioning.
(More on fixed positioning)
The containing block (="positioning context"): Positioning is relative to a containing block. For elements removed from normal flow by positioning with absolute, relative, or fixed, the containing block is the <html> "root" element, which is to say, the page itself.
But what if a positioned element is itself contained inside another positioned element?
- For a non-root element whose position value is relative or static, the containing block is formed by the content edge of the nearest block-level, table cell, or inline-block ancestor box.
- For non-root elements that have a position value of absolute, the containing block is set to the nearest ancestor (of any kind) that has a position value other than static. This happens as follows:
- If the ancestor is block-level, the containing block is set to that element's padding edge; in other words, the area that would be bounded by a border.
- If the ancestor is inline-level, the containing block is set to the content edge of the ancestor. In left-to-right languages, the top and left of the containing block are the top and left content edges of the first box in the ancestor, and the bottom and right edges are the bottom and right content edges of the last box. In right-to-left languages, the right edge of the containing block corresponds to the right content edge of the first box, and the left istaken from the last box. The top and bottom are the same.
- If there are no ancestors, the element's containing block is defined as the initial containing block.
An important point: elements can be positioned outside of their containing block. This is very similar to the way in which floated elements can use negative margins to float outside of their parent's content area. It also suggests that the term "containing block" should really be "positioning context," but since the specification uses "containing block," so wil I.
—Meyer, ibid., p. 303-304
Offset: Offsets include top, bottom, left, and right. The are given values of length, usually in pixels for screen media. The value positions the element relative to the containing block.
div#banner{position:absolute;top:15px;left:15px;height:120px;width:1200px;}
div#nav{position:absolute;top:150px;left:15px;width:120px;}
div#contents{position:absolute;top:150px;left:135px;width:1050px;}
Example 1: Here are three divs, with positioning, the outer div (grey) containing two inner divs. Notice that the right (green) div is positioned partially outside of its containing div:
Here is the html code (note that the CSS is set using the html style attribute within each div):
<div style="background-color:#666/*grey*/;width:300px;margin:20px 0;height:100px;border:2px outset #ccc;position:relative;">
<div style="background-color:#F93/*orange*/;width:100px;height:60px;border:2px outset #f93;position:absolute;left:15px;top:15px;" > </div>
<div style="background-color:#090/*green*/;width:100px;height:60px;border:2px outset #090;position:absolute;left:250px;top:-15px;" > </div>
</div><!--container div-->
Example 2: Here are the same divs, with the addition of some dummy text in the containing box. Notice that when the absolute positioning removes the two inner divs from the page, background content fills the void, creating an overlap:
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec diam turpis, luctus id tristique quis, scelerisque id tellus. Nullam at justo a velit porta dignissim. Fusce sagittis turpis felis, sit amet volutpat leo.
Example 3: Here are the same divs and dummy text as in example 2. Here, however, the position of the green element is changed from absolute to relative, preserving its original space, into which text does not flow; instead, the paragraph begins below the original position of the green div, which would have been in the top left of the container. The orange div, offset with position:absolute, continues to slightly overlay the text due to its 15px offset; the underlying text follows normal flow as though the orange div were no longer on the page. I have also removed the height property from the containing div, allowing the text to determine the height of its container.
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec diam turpis, luctus id tristique quis, scelerisque id tellus. Nullam at justo a velit porta dignissim. Fusce sagittis turpis felis, sit amet volutpat leo.
In some cases, a more satisfactory means of repositioning an element can be attained with floated elements and margins, which do not permit content to underlie the floated element or its margins! That is our next topic