This is probably something the rest of the world found out ages ago but I have only just discovered it. I was trying to find a problem with a page, granted the page was quite complex and consisted of a large amount of generated HTML but the problem boiled down to a simple issue: I did not understand how position:absolute worked in CSS.

I had a style like this

.interesting_p
    {
    	position: absolute;
    	top: 10px;
    	left: 10px;
    	margin: 0px;
    }

I had a P element using this style as its class. I expected the P element to be up near the top left hand corner of the browser window (10 pixels in and down). However it wasn’t anywhere near there so obviously I was not understanding the positioning attributes in CSS. I found a very interesting and useful article explaining how positioning works

An essential concept when it comes to absolute positioning is the containing block: the block box that the position and dimensions of the absolutely positioned box are relative to.

For static boxes and relatively positioned boxes the containing block is the nearest block-level ancestor—the parent element in other words. For absolutely positioned elements however it’s a little more complicated. In this case the containing block is the nearest positioned ancestor. By “positioned” I mean an element whose position property is set to relative, absolute or fixed—in other words, anything except normal static elements.

So, by setting position:relative for an element you make it the containing block for any absolutely positioned descendant (child elements), whether they appear immediately below the relatively positioned element in the hierarchy, or further down the hierarchy.

If an absolutely positioned element has no positioned ancestor, then the containing block is something called the “initial containing block,” which in practice equates to the html element. If you are looking at the web page on screen, this means the browser window; if you are printing the page, it means the page boundary.

When I looked through the page I did find that I did have a containing block that was not the whole page.

I stripped back my page to the simplest HTML that demonstrates the problem and it goes like this

<html> 
 <head> 
  <title>Positioning</title> 
  <style type="text/css"> 
   .container 
   { 
    background-color: Blue; 
    padding: 5px; 
    margin: 0px; 
   } 
   .interesting_p 
   { 
    background-color: Red; 
    margin: 0px; 
   } 
  </style> 
 </head> 
 <body> 
  <p>paragraph 1</p> 
  <p>paragraph 2</p> 
  <p>paragraph 3</p> 
  <p>paragraph 4</p> 
  <p>paragraph 5</p> 
  <p>paragraph 6</p> 
  <p>paragraph 7</p> 
  <p>paragraph 8</p> 
  <p>paragraph 9</p> 
  <div class="container">Container 
   <p class="interesting_p">ABS</p> 
  </div> 
 </body> 
</html>

The P with the class of interesting_p is the element I want to position, it is Red. The P elements with paragraph 1 to 9 are just there to push the red P down the page so that it is not already at the top of the page and so it will move when I position it. I have given the container padding so that we can see it around the red P, the container is blue. The page looks like this

pos1

Now if we just change the interesting_p class to position it at 10, 10 like this

.interesting_p
    {
   	background-color: Red;
    	position: absolute;
    	top: 10px;
    	left: 10px;
    	margin: 0px;
    }

then the page looks like this

pos2

This is what I would expect the red P element to always look like, after all it is absolutely positioned at 10, 10. However if we introduce a containing block by changing the container class like this

.container
    {
    	background-color: Blue;
    	position: relative;
    	padding: 5px;
    	margin: 0px;
    }

then the page looks like this

pos3

the absolutely positioned block is relative to the container. So the point to remember is before trying to work out why an element lays out at a particular position we must find the containing block. Its also worth remembering that it can affect Z-Index as well.