Absolute Positioning
Absolute positioning, by giving an element a style declaration position: absolute
, is one of the most powerful features of CSS. It allows elements to be placed anywhere on a page without interfering with other elements and for elements to be overlaid on others. This page describes how this method works.
Positioned or not?
Positioning of elements using CSS is determined by one of two properties 'position' and 'float'. Position may take one of four values:
- position:static
- position:relative
- position:absolute
- position:fixed
Considered together the chief characteristics of the various methods may be summarised.
Position method | Properties which apply | Behaviour | ||||||||
---|---|---|---|---|---|---|---|---|---|---|
top | right | bottom | left | width | height | z-index | Normal flow |
Scroll | Considered Positioned |
|
position: static | No |
No | No | No | Yes | Yes | No | Yes | Yes | No |
position: relative | Yes | Yes* | Yes | Yes* | Yes | Yes | Yes | Yes | Yes | Yes |
position: absolute | Yes | Yes | Yes | Yes | Yes | Yes | Yes | No | Yes | Yes |
position: fixed | Yes | Yes | Yes | Yes | Yes | Yes | Yes | No | No | Yes |
float: | No | No | No | No | Yes | Yes | No | No | Yes | No |
* Only one of 'left' or 'right' may be specified
In the table above it is important to note which of the methods are considered 'positioned'. This, possibly rather obscure, term is important when we consider absolute positioning. In particular note that position:static is not considered to be positioned and position:static is the default method which applies when no other is specified so all pages start using this method.
Containing blocks
Every html element, other than the html element itself, is contained in some other element. Typically a li element is contained in a ul element possibly a p element is contained in a div element. Moving up, the div, headings and paragraphs will be contained in the body element and the body in the html element.
Positioning an element
When any element is positioned, that is to say given a value relative, absolute or fixed for its position property, it is positioned within its immediate parent containing block if that block is itself positioned otherwise it is positioned within its first ancestor block which is positioned. Should no ancestor be positioned it is positioned within the initial containing block.
Padding Edge.
The padding edge of any element is the outer edge of its padding where it touches the inner edge of its border.
The positioned element may be offset by any of four offset properties top, right, bottom, left as shown in the figure. The offsets specify the distance of the outside margin of the block being positioned from the 'padding edge' of the containing block.
Initial containing block
What then is the initial containing block – the one used for positioning if nothing else is positioned?
For screen media, when a page is opened before scrolling occurs, the edges of the initial containing block are aligned with those of the viewport. That means that offsets are measured from the edges of the viewport. Once the page is scrolled the initial containing block scrolls also.
This concept may be a little difficult to grasp but reference to the demonstration files below will often clarify the issue. On the other hand a designer will rarely wish to position elements with respect to the initial containing block and will usually position some element and carry out further positioning with respect to this.
Positioning from scratch
Given the complication of the initial containing block it might seem that all positioning must ultimately be referred to the viewport. This is not so. It is only the offsets which are measured with respect to the viewport and that only sometimes. If no offset is specified i.e. if it is unmentioned rather than set to zero the positioned element will remain where it would have been in normal flow. In other words positioning the element need not necessarily change its position from where it was it may just change its status to 'positioned'. A method frequently employed is to set the declaration
position: relative;
either on the body or on a div without including an offset. It then becomes possible to position other elements with respect to the body or div without further ado.
Demonstrations
Demonstration 1 illustrates a simple page with fixed width and margins. In it are several squares each of which is styled as position: absolute;
The body contains a div (grid_holder) which has a background grid ruled at 20px and 100px. The positioned squares are the first items in the code in the body, being placed even before the grid holder, but, in spite of this, they occupy no space and the gridholder which follows them sits right at the top of the body; it holds the main heading and the rest of the page content. In this demonstration all positioning takes place with respect to the initial containing block (i.c.b.). text in the demonstration tells you what to look for.
Alter the viewport width and height and satisfy yourself that the squares appear in the expected positions.
As you progress through the demonstrations you may find the following table useful in describing the differences.
Demonstration | Body width | Body position | Body margin | Grid holder position | Grid holder margin | Positioning container |
---|---|---|---|---|---|---|
1 | Fixed | - | 50px | - | - | i.c.b./viewport |
2 | Fixed | - | auto | - | - | i.c.b./viewport |
3 | Fluid | - | 50px | - | - | i.c.b./viewport |
4 | Fixed | relative | auto | - | - | body |
5 | Fluid | relative | 50px | - | - | body |
6 and 6a | Fluid | relative | 50px | relative | 75px | grid |
7 | Fluid | relative | 50px | - | - | body |
8 | Fluid | relative | 75px | relative | 25px | grid |
Demonstration 2 uses exactly the same code for body and squares. The only difference is that the body margins are styled differently so that the body should be centred horizontally in the viewport.
Demonstration 3 again uses the same code but this time the body has no width specified so expands to fill the available viewport subject to the margins set.
In all these schemes items which are absolutely positioned are positioned with respect to the initial containing block. In the first and third schemes the fixed margin provides a known relationship between the initial containing block and the body so, by using offsets top and left only, authors have the means of positioning items where desired.
The second demonstration which uses a centred body with fixed width is an arrangement much favoured by authors. Unfortunately the lack of a simple relationship between the initial containing block and the body makes it very problematic when positioning items. What is really required is the ability to position items with respect to the body.
Demonstration 4 shows how this can be achieved. In this case the code employed is identical to that for demonstration 2 except that the body is styled as position: relative;
Reference to table earlier shows that this defines the body as 'positioned'. Elements contained in the body are now positioned with respect to the body. This greatly simplifies design. The author may use any of the offsets top, right, bottom, left and position elements reliably in respect to the body.
Note that though the body is styled with position: relative;
it is not necessary to specify any offsets.
Demonstration 5 simply demonstrates that the same may be achieved when the body width is fluid.
While working near the top of a page it may be satisfactory to position elements in the body but moving down the page you often need to be able to re-set the positioning 'zero point'. Ideally you should be able to select any area on a page and measure the offsets from there.
Demonstration 6 shows how this may be done. The body is now shown with a light gray border and after a few in-flow text items comes the grid holder. This has left and right margin just to clarify the difference between it and the body but importantly it has position: relative
. The code for the squares is placed as the first items in the grid holder. The squares will now be positioned with offsets measured from the edges of the grid holder.
With all the demonstrations and with all positioning methods setting an offset defines the location of the edge of an element. Sometimes an author may prefer to define the position of the centre of an element. Provided that the dimensions of the element are known this is possible and, in fact, all the demonstrations have centred square 7 horizontally.
Demonstration 7 shows how a line of elements may be evenly spaced across the width of a div and the vertical centres placed on the bottom of a div. The technique is to specify the position of one edge then set a negative margin of half of the width or height as appropriate.
Demonstration 8 In the previous demonstrations all the absolutely positioned elements have had fixed width. This demonstration shows a number of different situations in which the width is either uncontrolled, thus determined by the content, or set by using left and right offsets on the same element. So as to differentiate between the body and the positioned containing element the general scheme is the same as in demonstration 6. The demonstration page describes what is expected in each situation.
To note
When using absolute position there are a few things that you may need to note.
- Elements absolutely positioned are not in the normal document flow. This means that they may overlay other elements. This allows you to layer elements on top of each other. The
z-index
property controls the order of the layers. - Because absolutely positioned items are not in the document flow it is not normally possible to return and use normal flow and work on the page below an absolutely positioned item. The exception would be where the height of the absolutely positioned element is known and a margin or other space is allowed in the document flow to accommodate it. In this they differ from floated elements which are are removed similarly from normal flow but which may be cleared to return to normal flow.
- The previous note does not mean that elements contained in an absolutely positioned item do not establish a new flow stream, they do and elements may be relatively or absolutely positioned in an absolutely positioned container.
- When the width of an absolutely positioned element is not specified typically content will wrap at the right hand side of the containing block while fixed width elements may extend outside the containing block. If both left and right offsets are set, wrapping will occur at the offset limit and the width will be established by the left and right offsets. With MSIE≤6 if no width is set the element shrinks to fit but wrapping occurs as described.
- Browsers, other than MSIE≤6, will allow you to scroll to absolutely positioned elements which extend to the right or below the body but elements extending above and to the left will be truncated.
Bugs
Most browsers render absolute positioning completely correctly but with MSIE≤6 two problems may occur.
-
MSIE incorrect container bugs.
This bug was encountered in demonstrations 6 and 8. It occurs when absolute positioning is carried out within a relatively positioned container which has neither width not height specified. It has various effects leading to elements disappearing or being mispositioned. It is most serious when right and/or bottom offsets are used.
Various fixes are available the simplest is to give the container a small height and to target this only at IE≤6 as explained in Targeting CSS. Due to another bug IE≤6 ignores this height but the behaviour is corrected. -
MSIE adjacent floats bug
If the code for an absolutely positioned element is immediately adjacent, either before or after, to that for a floated item the absolutely positioned element may disappear. The conditions under which this bug is seen are rare but have been itemised by Bruno Fassino. When the conditions apply no remedy is available using CSS; the only option is to rearrange the html code, if necessary adding a dummy div as a buffer between the interfering elements.