CSS Positioning: Relative & Absolute Tutorial
To understand CSS Positioning, you need to start with how a browser works. When a browser begins to render an HTML document, it starts at the top of the window and works its way down through the document's contents, allocating window space as needed. Unless the size of the document is specifically limited by a CSS instruction, the browser continuously expands the document vertically to accomodate all of the content. This property of vertical expansion applies to all block level HTML elements, which makes sense because <HTML> and <BODY> are both block level elements. To continue, each new block-level element (DIV, P, TABLE, FORM, etc.) is rendered on a new line. Inline HTML elements (IMG, SPAN, INPUT, etc.) are rendered horizontally as they are encountered in the document until the content reaches the horizontal boundary of the parent/containing block level element, at which point rendering is continued on the next vertical line. This is called the normal document flow, which is important to keep in mind here.
Normal Document Flow
Let's start with the example shown below which shows a containing block level element (a <DIV>), inside which are nested two block level elements outlined in blue. Both of the nested block level elements contain some inline level elements outlined in red. Note how BLOCK LEVEL ELEMENT 1 is automatically expanded vertically to accomodate the space required to display the additional inline elements it contains compared to BLOCK LEVEL ELEMENT 2. Both of the nested block level elements have a default CSS "position" property setting of "static", which means they are rendered strictly within the normal document flow.
The next example illustrates relative positioning, which (like "static" positioning) works on the principle that elements that are assigned relative positioning are rendered with respect to their position within the normal document flow. But unlike "static" positioning, elements using relative positioning may be positioned higher or lower, further left or right within the normal document flow. As each relatively-positioned element is rendered, space within the document is allocated to it. Block level elements set to "position:relative" force the start of a new "line". That is, the rendering of a new block-level element begins at the next line down within the document flow. Inline elements are rendered on the same line until the vertical/edge boundary of the containing block level element is reached, at which point a new line is started and rendering continues. Notice that the parent containing block element automatically expanded vertically to accomodate the additional child content line blocks. I used <DIV>s, but I could just as well have used a <p> or any other block level element for the nested blocks.
In the example above, the bottom BLOCK LEVEL ELEMENT 2 was assigned a CSS style setting of "position:relative;", but with added positioning settings of "top:15px; left:15px;" to move it from it's normal position within the normal document flow. As you can see, it overflows the outer boundary of the parent containing block with the black outline, even though space for it had been allocated within the parent block, as normal. I rarely find it necessary to use relative positioning to control the layout of my designs this way, but it does happen, so you need to be aware of how it works. The vast majority of my using relative positioning is actually in conjunction with absolute positioning. The next section explains the reason for this.
Absolute positioning often causes confusion for beginners, but it's really simple once you understand a couple of things: (1) how it affects the other elements in the document, and (2) how the position of the element is calculated. We need to start with some dry technical explainations, but we'll wrap things up with a simple general explanation.
The first difference between aboslute positioning and relative (or static) positioning is that elements with absolute positioning are removed from the normal document flow. That is, their presence in the HTML document does not affect where other elements in the document are rendered in the browser window, and no space for them is automatically allocated as it would be for elements using relative or static positioning. The second, and most important principle to understand about absolute positioning is that elements assigned absolute positioning are positioned with respect to their parent positioned element. So, to use absolute positioning effectively, you need to start by explicitly setting the 'position' property of the containing block level element using either "position:relative" or "position:absolute".
Example 1: THE WRONG WAY
Let's start with the same HTML code we used for the Relative Positioning example above. By changing the CSS on BLOCK LEVEL ELEMENT 2 to "position:aboslute;", it is now removed from the normal document flow and the browser does not allocate space for it within the document. Because of that, it is positioned in relation to the parent-positioned element (the containing block), and overwrites BLOCK LEVEL ELEMENT 1 - creating a mish-mash. If you see this kind of effect in your documents, it means that you have either not properly assigned a CSS position setting for the parent containing element, or you have not properly allocated space for it within your document.
Example 2: THE RIGHT WAY
To remedy the situation in this case, I simply changed the CSS 'height' property on the containing block level element outlined in black to allocate vertical space to hold BLOCK LEVEL ELEMENT 2. Changing the height of the container is just one way to allocate space in a document, of course. To make room for positioned elements, you might well have to adjust the "width" or "margin" properties of adjacent elements. In this case, we did it by adding a CSS rule for "height" for the parent-positioned element, and setting an appropriate "width" and "height" setting on the "position:absolute;" BLOCK LEVEL ELEMENT 2.
In short, the two keys to using absolute positioning are: (1) You must explicitly set the "position" property of the parent containing element with "position:relative" or "position:absolute", and (2) You must be sure to explicitly allocate space for the positioned element within the document with your CSS settings. Simply put, you need to give the browser a fixed starting point to base the positioning, and remember to make room in the document for the elements using "position:absolute;". That's all there is to it.
If you examine the source code for this page, you'll see that there is a lot of inline styling. That is, many elements use the "style" attribute to set the various CSS properties. I used inline styles here for your convenience so that you could more easily see how the various CSS rules affect the display. You should always avoid using inline styles and rely on your stylesheet to control the CSS for your pages. It helps keep your HTML source code cleaner and easier to maintain when all of the CSS is in one location.
One last thing that really should come first: You should always use a complete <!DOCTYPE> statement at the start of all of your HTML documents to force browsers into Standards-Compliance Mode. The original browser wars between Microsoft and Netscape brought with them an enormous number of differences in how they interpreted Cascading Style Sheets and rendered web pages. Sanity prevailed when the browser makers all started to work toward compliance with the W3C standards, but to accomodate legacy websites that had been built over the years, browsers default to their older methods unless a complete <!DOCTYPE> (or the HTML 5 "<!DOCTYPE html>" DOCTYPE) is used to signal them to use standards-compliant methods. See the Microsoft Developer Network Library for more information on the history of their Box Model and CSS Positioning in general, and how to choose and use a complete <!DOCTYPE> statement that's best for your pages.
For complete technical details, see the W3C documentation on The Box Model, and Visual Formatting Model. They're both dry, technical documents, but so well-illustrated that you'll easily understand the principles being discussed. You'll also find the Index of HTML Elements handy for determining whether an element is a block-level or inline and the attributes available for each one. And I also suggest bookmarking the CSS Property Index as your reference source for CSS properties and using them properly.
This page was last modified on November 13, 2014