Relatives – Who needs them?
Often times while helping people with their CSS layouts I see a misuse of position:relative – where the author hasn’t quite understood what relative positioning is all about. The result is that the page becomes overly complex and every element needs to be adjusted to cater for the perceived movement of the relatively placed element. In the end the layout becomes unmanageable and unworkable.
In this article we will look at what CSS relative position is, what it isn’t and how to correctly implement it.
What does relative positioning actually do?
In one sense relative positioning does nothing at all!
That is to say that it has no effect whatsoever on the flow of the document. Although this may seem strange what relative positioning does is that it moves an element visually but not physically. According to all the other elements on the page the element is still in its original position and they will react to it as though it were still in the space it originally occupied in the normal flow of the document.
In technical terms the element is moved the specified distance but the space it previously occupied is preserved. Therefore if you move an element using top:-200px then you will find that there is now a big gap in the page where the element originally was and all content is treating that gap as though it were the original element.
In its new position the moved element will have no effect on surrounding content except perhaps to overlap or obscure things depending on where it has been placed. So you see relative positioning isn’t really used for structural layout in the same way that absolute positioning or floated elements are used.
What is it relative to?
This is a common question and a lot of people think its relative to the viewport or perhaps its parent. It’s none of these and a relatively positioned element is basically relative to itself.
It doesn’t matter what its parent is. The element will be moved the specified distance from where it was and then placed at the new position. If you say top:10px then the top of the element is moved down the page by 10px from where it started. This is in fact the same as saying bottom:-10px.
- When you use top with a positive unit you move the top of the element from the top downwards by the specified dimension thus moving the whole element downwards.
- When you use bottom with a positive unit you move the bottom of the element from the bottom upwards.
- When you use left with a positive unit you move the left of the element from the left towards the right.
- When you use right with a positive unit you move the right of the element from the right towards the left.
As mentioned above using negative values is allowed and will move the element in the opposite directions to those specified above. So top:10px is the same as bottom:-10px and left:10px is the same as right:-10px.
What can we use relative positioning for?
As already mentioned above relative positioning isn’t generally used for structural layout but is more used for more subtle effects. This could be that you want to overlap one element with another without altering the flow of the document at all. If you used negative margins to overlap an element then you would find the flow of the page would also be affected by this 10px shift. Whereas with a relatively positioned element there will be no change to the flow of the page at all and only the relative element gets moved. Everything else remains where it was and totally unaware that anything has happened.
This can be very useful for instances where everything on the page is perfect but you perhaps need to move one element by a couple of pixels without everything else following suit.
You can also use relative positioning for swapping the order of columns in a floated layout without having to change the source order of the html. If you have three floated columns for example all at 250px wide and you have them all floated left then they will all line up in html order of float1,2 and 3. However you may want to have the middle column content first in the html for SEO and accessibility reasons as your side columns may just be advertisements or information that are not as important as the middle column.
Using relative positioning you can make that first float appear in the center of the page as your layout requires but also have it first in source in the html. This is simply accomplished by applying a relative position to the first float in source that will shift it 250px to the right. Of course this will make it overlap the second float so we apply the reverse logic to the second float and using a negative margin shift it into the space vacated by our first column. These movements will have no other effect on the page except to have juxtaposed the positions of the first and second columns.
Here is the basic code to achieve that effect:
- <div id="col1">Test Column 1</div>
- <div id="col2">Test Column 2</div>
- <div id="col3">Test Column 3</div>
In order to show it working in a proper layout with margins and content I have put up a live example so you can see it in action (view source to see the code).
As you can see relative positioning is a very powerful tool indeed when used correctly.
Why do I often see elements with position:relative on them but no positions specified?
This is another aspect of relative positioning and that is it has the effect of producing a "local stacking context" for further positioned elements. It also allows a z-index to be applied and controlled as only positioned elements (not static elements i.e. the default state) can have a z-index applied to them.
When you apply position:relative to an element it will create a local context so that if you use absolute positioning on any of its children then this relatively positioned elements becomes their starting point and not the viewport. The containing block for the absolutely positioned element is the nearest ancestor that has value for the property "position" other than static. If there is no such parent then the containing block is the root element which is the html element not the body.
Therefore if you want to place an absolutely positioned element inside a static container and have it stay in relation to that container at all times then you add position:relative to the static container and you have created a local stacking context. This will not affect the layout at all because you have not supplied any positional changes (e.g.
top,left,right or bottom) and therefore there is no detrimental affect to your layout at all. This is in fact the most common use for position:relative and it is only to create this "local stacking context" and not in fact move the element at all.
What is z-index used for?
As this topic is about relative positioning I will only briefly mention this in passing. Only positioned elements can have z-index applied which means that if you want to place one element on top of another then you can control the stacking order by manipulating the z-index. Therefore if an absolutely positioned element overlaps your static container you can apply position:relative to your static container and apply a higher z-index to bring it on top.
Of course things are never as simple as that and the fact that an element has a higher z-index than something else doesn’t always mean it will be on top. It also depends on the z-index level of the parent of that element (if there is one). It is the parents z-index that dictates whether its children will overlap other elements on the page and the parents z-index would need to be higher than the z-index of the other elements parent.
Use negative z-index with care as browsers are buggy with this and you cannot put a child behind the parents background (although some browsers like IE6 may allow this). In complicated z-index situations IE6 is a bit buggy and may not always do what you expect (as usual) , so use with care.
So a quick recap with five basic things to remember about relative positioning:
- the element is positioned relative to where it would usually be in the normal flow of the document
- the space that the element occupies in the normal flow is preserved, which may mean that you are left with a gap if the element is positioned a long way away
- the element may overlap other elements on the page.
- relative position sets a stacking context for further absolutely positioned elements.
- position relative can be used so that z-index will take affect and can be applied
That about wraps it all up relatively speaking of course.