Using CSS Fixed Position Elements Across Browsers Without Javascript
Yesterday, I posted my first experimentation with CSS fixed-position elements and getting them to work across all browsers, including IE6. The solution I demonstrated yesterday involved using proprietary Javascript expressions in the CSS that would be used by IE6; this technique worked pretty well, but caused a jittery effect as the "fixed" position elements repositioned themselves during page scroll.
While I was doing research on using the "position: fixed" CSS property, I came across two solutions for getting fixed-position elements in IE6. The first was the one that I demonstrated yesterday; the second one was to fake fixed-position elements by making them absolutely-positioned elements. In order to get that to work, however, we need to move the primary content out of the BODY tag and into a sub-content tag. This way, the BODY tag can have a height / width of 100% which will work for absolutely-positioned elements, while the sub-content container can take care of the scrolling:

With this page architecture, since the BODY tag does not scroll, elements within the BODY tag, but outside the sub-content container, can be positioned absolutely and will act just as if they were fixed-position elements. Here is the sample page that I created:
<!DOCTYPE HTML> | |
<html> | |
<head> | |
<title>Using CSS Fixed Position Across Browsers</title> | |
<style type="text/css"> | |
html, | |
body { | |
margin: 0px 0px 0px 0px ; | |
padding: 0px 0px 0px 0px ; | |
} | |
#site-body-container {} | |
#site-body-content { | |
padding: 15px 15px 15px 15px ; | |
} | |
div.fixed-position { | |
background-color: #F0F0F0 ; | |
border: 1px solid #CCCCCC ; | |
height: 48px ; | |
line-height: 50px ; | |
position: fixed ; | |
text-align: center ; | |
width: 148px ; | |
z-index: 1000 ; | |
} | |
div.fixed-n { | |
left: 50% ; | |
margin-left: -75px ; | |
top: 0px ; | |
} | |
div.fixed-n-e { | |
right: 0px ; | |
top: 0px ; | |
} | |
div.fixed-e { | |
margin-top: -25px ; | |
right: 0px ; | |
top: 50% ; | |
} | |
div.fixed-s-e { | |
bottom: 0px ; | |
right: 0px ; | |
} | |
div.fixed-s { | |
bottom: 0px ; | |
left: 50% ; | |
margin-left: -75px ; | |
} | |
div.fixed-s-w { | |
bottom: 0px ; | |
left: 0px ; | |
} | |
div.fixed-w { | |
margin-top: -25px ; | |
left: 0px ; | |
top: 50% ; | |
} | |
div.fixed-n-w { | |
left: 0px ; | |
top: 0px ; | |
} | |
/* -------------------------------------------------- */ | |
/* -- IE 6 FIXED POSITION HACK ---------------------- */ | |
/* -------------------------------------------------- */ | |
html, | |
body, | |
#site-body-container { | |
_height: 100% ; | |
_overflow: hidden ; | |
_width: 100% ; | |
} | |
#site-body-container { | |
_overflow-y: scroll ; | |
_overflow-x: hidden ; | |
_position: relative ; | |
} | |
div.fixed-position { | |
_position: absolute ; | |
} | |
/* For the scrollbar. */ | |
div.fixed-n-e, | |
div.fixed-e, | |
div.fixed-s-e { | |
_margin-right: 16px ; | |
} | |
/* For the scrollbar. */ | |
div.fixed-n, | |
div.fixed-s { | |
_margin-left: -83px ; | |
} | |
</style> | |
</head> | |
<body> | |
<div class="fixed-position fixed-n"> | |
North | |
</div> | |
<div class="fixed-position fixed-n-e"> | |
North East | |
</div> | |
<div class="fixed-position fixed-e"> | |
East | |
</div> | |
<div class="fixed-position fixed-s-e"> | |
South East | |
</div> | |
<div class="fixed-position fixed-s"> | |
South | |
</div> | |
<div class="fixed-position fixed-s-w"> | |
South West | |
</div> | |
<div class="fixed-position fixed-w"> | |
West | |
</div> | |
<div class="fixed-position fixed-n-w"> | |
North West | |
</div> | |
<!-- ------- --> | |
<!-- ------- --> | |
<div id="site-body-container"> | |
<div id="site-body-content"> | |
<div style="height: 3000px ;"> | |
<p> | |
Lorem ipsum dolor sit amet, consectetur | |
adipiscing elit. Aliquam dictum enim in mauris | |
luctus convallis. Aliquam erat volutpat. | |
Suspendisse potenti. Duis blandit, urna vitae | |
feugiat porttitor, risus est ornare metus, at | |
dignissim urna velit id enim. Donec lectus nisi, | |
consectetur eget sollicitudin id, bibendum | |
laoreet velit. | |
<p> | |
</div> | |
</div> | |
</div> | |
</body> | |
</html> |
You'll notice that the standards-compliant browsers still use "position: fixed". Only IE6 (with the help of the underscore ("_") hack since my IE doesn't allow conditional comments) falls back on this sub-content container work around. Because the content scrollbars are not part of the main window, our right-aligned and center-aligned "fixed" position elements need to take some additional margin into consideration to prevent overlapping with the content container's scrollbar.
Here is a screen shot of IE6 using the above code:

And, since this solution does not use any proprietary IE-based Javascript expressions, scrolling around the window does not lead to any jittering.
Want to use code from this post? Check out the license.
Reader Comments
Nice article.
I want to add important note about this usage.
If !Doctype is not used, position:fixed doesn't work on Internet Explorer.
Nice solution.
It may interest you to watch this screencast (in Russian only, sorry) - http://www.artlebedev.ru/tools/technogrette/html/emulate-fixed/
Examples can be downloaded by clicking ??????? at the bottom of the page.
@Memiso,
I hope people are *always* using doctypes.
@Oleg,
Thanks, I'll take a look.
Doctype really cause lot's of issue with IE6
Is there any ways to disable scroll bar, because it is unnecessary.
@Anil,
I am not sure you can remove them when not necessary. I know you can add them when not necessary.
I'm wondering, in your example above:
/* -- IE 6 FIXED POSITION HACK ---------------------- */
/* -------------------------------------------------- */
html,
body,
#site-body-container {
_height: 100% ;
_overflow: hidden ;
_width: 100% ;
}
#site-body-container {
_overflow-y: scroll ;
_overflow-x: hidden ;
_position: relative ;
}
do you think your second "#site-body-container" was meant to be "#site-body-content"
#site-body-content" would be missing and it wouldn't make sense that you had called out "#site-body-container" twice
Apart from that -Thanks for this really well organized tutorial. Best I've ever seem in regards to making your point succinctly.
@Stacey,
Without having the code in front of me, it definitely looks a bit confusing to run; but, I think it is accurate. The reason it is repeated is because it is sharing the height/width definitions with the html and body elements.
Admittedly, this is confusing. I was probably trying to be clever. In reality, I would have broken those apart and just defined the site-body-container once.
That said, thank you for the kind words!
Nice article. thank you.
But how can i position elements fixed, which are NOT fixed-width ?
it means, width of elements are flexible by contents...
@Chamisak,
This should work with non-fixed-width elements. You can always position an element with an automatic width. However, whether or not that typically works for a good layout - that is on a per-case basis. But, at the end of the day, as long as you position the element, you should be fine.
Do you have a fix for IE8? It's not scrolling properly, and I cannot figure it out.
Now my css for jswindow has a fixed and centered position but, that fixed position is refering at the iframe from page2.
My question is how can i make position against the page2 and not the inside iframe?
Is there a posibility to do that using css? or i have to javascript?
Anyone got a sugestion for this?
MEMISO: You saved my life on this with the !DOCTYPE point. Thank you!!
Terrific! I easily place fixed position at every corner but found problem in centering. Sure this great article kill my headache. Good Job!
Can anyone tell me, how to make a widget sticky using the same concept?
We need not be tricky to make across combat-able fixed layer.
Just add the line
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
in the header and use fixed positioning in css. Tested in
Thank you
George Thengummoottil
We need not be tricky to make across combat-able fixed layer.
Just add the line
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
in the header and use fixed positioning in css. Tested in ie,ff,gc,op
Thank you
George Thengummoottil