July 14th, 2008 - by Paul OB

Now that IE7 has overtaken IE6 in usage it has become more common to find authors trying to use position:fixed in their layouts. Therefore in this article we will try to address some common problems and misconceptions when using position:fixed (we will not be covering the background-attached “fixed” property but you can find out more about that here if you are interested.).

Note that position:fixed doesn’t work in IE6 and under so you will need to be using another browser although we will try to accommodate IE6 with some alternate styling.

Fixed to What?

Fixed positioning varies from other positioned elements in that the element is always placed in relation to the viewport and not a local stacking context. Even if you add position:relative to a parent of the fixed element it is still placed in relation to the viewport.

This can present problems if you want to place the fixed element inside a centered layout and then place it at a certain position within that centered layout.

In order to have a positioned element inside a centered layout you can simply let it occupy its normal position in the flow and not specify any position values for top, bottom, left or right at all. This will enable the element to become fixed at that point while the rest of the content scrolls.

We’ll work through some simple examples to show this in effect.

We’ll start with this simple Example

  1. body{text-align:center;}
  2. #outer{
  3.     width:600px;
  4.     margin:auto;
  5.     border:1px solid #000;
  6.     position:relative;
  7. }
  8. #side{
  9.     position:fixed;
  10.     background:red;
  11. }
  1. <div id="outer">
  2.     <div id="side">Fixed Sidebar</div>
  3.     <p>scrolltest</p>
  4.     <p>scrolltest</p>
  5.     <p>scrolltest</p>
  6.     <p>scrolltest</p>
  7.     <!-- add more elements to test scrolling-->
  8. </div>

Figure 1

As you can see from the example above this places the fixed element exactly at the top of our outer div and it remains there even though content will scroll. Try scrolling the page up and down and you will see that the fixed element always remains in view.

Let’s see what happens if we now try and add some positioning to move it into another position.

  1. #side{
  2.     position:fixed;
  3.     background:red;
  4.     left:100px
  5. }

Figure 2

The fixed element has now jumped out of the centered container and is placed 100px from the left of the viewport. It ignored the centered container’s position altogether!

This is because as mentioned above fixed elements are always placed in relation to the viewport so we cannot use top, bottom left or right when we want to position within another element.

Margins to The Rescue

Fortunately we can use margins to push our fixed element around inside our centered block.

  1. #side{
  2.     position:fixed;
  3.     background:red;
  4.     margin-left:100px
  5. }

Figure 3

That pushes the element nicely into position as shown in Figure 3 above.

Although we have shown that the fixed element can in fact stay in tune with our centre element it should be noted that the fixed element won’t be constrained by this parent and should content stretch the fixed element wide it would just overflow at the edges of the centred container. You would need to set a specific width if you wanted to constrain the width to match its current location.

Fixed Footer

We have now established that we can’t use positioning inside our centered element so how can we place a fixed footer at the bottom of this container? A top margin can’t be used this time because we don’t know the height of the element and it will of course vary depending on content. If we use the position value of “bottom” then the fixed element will jump to the bottom of the viewport and not the bottom of the element we are concerned with.

In fact the answer lies once again in first using the normal rules of positioning to achieve the layout you want and then fixing the element once the layout is correct.

First of all we achieve the look we want without using fixed positioning.

One way this can be done is to absolutely position an element at the bottom of our layout and then add an inner element that is set to position:fixed. This means the element will be placed at the bottom of the layout and then it will be fixed at that exact position.

Here is the example:

  1. #outer{
  2.     width:600px;
  3.     margin:auto;
  4.     border:1px solid #000;
  5.     position:relative;
  6.     overflow:auto;
  7. }
  8. #base{
  9.     position:absolute;
  10.     bottom:0;
  11.     left:0;
  12.     height:50px;
  13.     width:600px;
  14. }
  15. .inner{
  16.     position:fixed;
  17.     background:red;
  18.     width:600px;
  19.     height:50px;
  20. }
  1. <div id="outer">
  2.     <p>scrolltest</p>
  3.     <p>scrolltest</p>
  4.     <p>scrolltest</p>
  5.     <p>scrolltest</p>
  6.     <p>scrolltest</p>
  7.     <p>scrolltest</p>
  8.     <p>scrolltest</p>
  9.     <p>scrolltest</p>
  10.     <p>scrolltest</p>
  11.     <p>scrolltest</p>
  12.     <p>scrolltest</p>
  13.     <p>scrolltest</p>
  14.     <p>scrolltest</p>
  15.     <!-- add more elements to test scrolling-->
  16.     <div id="base">
  17.         <div class="inner">Fixed base to centered element</div>
  18.     </div>
  19. </div>

As you can see in Figure 4 the element is now placed at the bottom of our layout but because #outer isn’t scrolling it appears to be doing nothing different from an absolute element.

Figure 4


If we shorten the viewport to cause scrolling then we find that our fixed footer has been fixed below the viewport and is invisible as shown in Figure 5 or see for yourself in this Example 2.

Figure 5

This brings up an interesting problem when using fixed positioning in that when the element lies outside the viewport it becomes unreachable. Bear this in mind and always make sure you can reach the element in some way. This usually means making sure the fixed element is high in the viewport or is at least fixed to the viewport in some way.

We can’t really use this method for our fixed footer because it serves no purpose if we can’t see it. A change of tact is needed and we will need to fix the footer to the bottom of the viewport using the bottom property while not specifying left or right positions so that our element holds true to the centered layout. However we will also need to use a 100% high centered layout if we want borders to meet the footer, otherwise it may look a bit detached. (Read my explanation on 100% height in the middle paragraphs here.)

Here is the example and the resulting code is as follows.

  1. *{margin:0;padding:0}/* quick and dirty reset for demo only - use a proper reset */
  2. html,body{height:100%}
  3. h1,p{margin:0 0 1em 0}
  4. body{text-align:center;}
  5. #outer{
  6.     width:600px;
  7.     min-height:100%;
  8.     margin:auto;
  9.     border:1px solid #000;
  10.     border-top:none;
  11.     border-bottom:none;
  12.     position:relative;
  13.     text-align:left;
  14. }
  15. * html #outer{height:100%}/* for ie6 and under who will just get an absolute footer instead */
  16. #base{
  17.     position:fixed;
  18.     bottom:0;
  19.     height:50px;
  20.     width:600px;
  21.     background:red;
  22. }
  23. * html #base{/* for ie6 and under*/
  24.     position:absolute;
  25.     bottom:0;
  26.     left:0;
  27. }
  28. p.last{
  29.     padding-bottom:60px;/*make final text appear above footer */
  30. }
  1. <div id="outer">
  2.     <h1>Fix your CSS</h1>
  3.     <p>A small example of using position:fixed in compliant browsers (not IE6 and under)</p>
  4.     <p>scrolltest</p>
  5.     <p>scrolltest</p>
  6.     <p>scrolltest</p>
  7.     <p>scrolltest</p>
  8.     <p>scrolltest</p>
  9.     <p>scrolltest</p>
  10.     <p>scrolltest</p>
  11.     <p>scrolltest</p>
  12.     <p class="last">scrolltest</p>
  13.     <!-- add more elements to test scrolling-->
  14.     <div id="base"> Fixed base to centered element</div>
  15. </div>

You will note from the above code I have added some padding to the last element so that the text is not covered up by the fixed element. Otherwise the last piece of text would sit underneath the footer and not be seen. I have also added a hack so that IE6 and under just gets a position absolute footer and will still be quite functional although it won’t be a fixed footer. In dynamic situations (e.g. dynamically inserted content of JavaScript content switches) IE6 can forget where the absolute footer is so you need to take care when using it in dynamic situations. (Although as an aside I have found that if you are doing a content hide and show with javaScript you just need to nudge the footer with some JavaScript also and then it remembers where it was.)

If you really want IE to join the party then the easiest way is to use an IE expression to imitate position:fixed.

Here is another example that will work in IE6.

The expression is as follows.

  1. <!--[if lte IE 6]>
  2. <style type="text/css">
  3. html{background:url(fake.gif) no-repeat 0 0}/* use a 1px x 1px transparent gif which cures the jitters on the footer when using this expression*/
  4. #base {position: absolute;
  5. top:expression(eval(document.compatMode &&
  6. document.compatMode=='CSS1Compat') ?
  7. documentElement.scrollTop
  8. +(documentElement.clientHeight-this.clientHeight)
  9. : document.body.scrollTop
  10. +(document.body.clientHeight-this.clientHeight));}     
  11. </style>
  12. <![endif]-->

Be aware that expressions only work when javascript is enabled. You can read more about expressions here and if you are also unfamiliar with conditional comments you can also read up on them here.

There is a CSS way of imitating position fixed in IE6 without using expressions or Javascript but it takes a lot of effort and is rather a risky process. If you want to take a look then I have some examples below but I will not explain them today (and they are mainly experimental and not something I would advocate using). However they are quite interesting.

Example1
Example 2
Example 3
Example 4

I hope that your CSS is now well and truly fixed!

Be Sociable, Share!

8 Responses to “Fix Your CSS”

1 H.

Paul,
I’m having problems with this in IE7. Viewing your page of the first example in IE7,
http://www.pmob.co.uk/search-this/fixed1.htm
it is showing the fixed element at the center of the outer div, not at top left corner as shown in Figure 1. Making my own test page of your code results in the same problem. Adding the step with the 100px margin moves the fixed element about 100px to the right of center. I receive the same problem viewing the footer example as well. Of course, everything works fine in Firefox and Safari.
Any thoughts?

2 Paul OB

Hi H,

Thanks for spotting that IE7 bug :(

I thought i’d checked IE7 but I think I checked before I added the text-align:center to the body.

IE thinks an auto position is relevant to the alignment of the text so id you use text-align:center then the auto position incorrectly gets centered (I believe the same happens with text-align:right)

Therefore the fix is simply to add text-align:left to #outer and then center the internal elements instead.

I have updated the example.

Thanks for pointing it out and sorry I missed it first time around :)

3 Brady J. Frey

I appreciate the article, it’s good to reference for the designers in my office. Would have loved it if you’d use semantic code, instead of some nested divs with content so I didn’t have to reexplain ‘don’t do that, you’re wasting ranking and accessibility popping that text just in a div when it has semantic value…’

4 Quote Catcher Website Design

This is great stuff – laid out and everything. Thanks for the examples — bookmarking now!

5 Paul OB

Hi Brady,

Thanks for the comments :)

Of course semantic html should be the object of all our desires but I do tend to keep these examples more generic so its easier for others to understand.

The articles are more concerned with showing how things work but of course as you rightly say they should then be incorporated semantically into the layout in question.

Maybe in future, I’ll also show a real world example as the last example.

6 Brady J. Frey

Thanks for the great follow up Paul;)

8 Sutapa

Thanks for this css.

Share your thoughts...

mulberry sale spyder womens jacket cheap new balance 574 mulberry outlet cheap new balance 574 arcteryx outlet mulberry sale spyder womens jacket mulberry sale spyder womens jacket mulberry outlet mulberry outlet new balance 574

Popular Articles

Top 10 Commentators


Subscribe to this feed! Subscribe by Email!

Random Bits Podcast

You need to download the Flash player from Adobe

Blogs Worth Reading