Using CSS Fixed Position Elements Across Browsers
Even after years of web development, one thing that I never really looked into was fixed-position elements. I've seen them used on websites, and I generally like what they do; but, I've simply never taken the time to look into it. So, I figured this morning would be just as good a time as any. If you are not familiar with what a fixed-position element is, when you apply the following CSS to an element:
position: fixed
... you generate an absolutely positioned element, in which the given element is positioned relative to the browser window and not to any parent element of the DOM. Meaning, if you have the following CSS:
left: 0px ;
position: fixed ;
top: 0px ;
... on a given element, the element will always be in the top-left corner of the window no matter what kind of scroll position you have.
As it turns out, creating fixed-position elements is extremely easy using this kind of basic CSS - unless of course you need to support IE6. To IE's credit, however, IE7 and up support the "position: fixed" rule in standards-compliant mode (which we should all be using). If you do need to support IE6, though, you can get it to work using a proprietary IE feature in which CSS rules can be written as Javascript expressions. I haven't used this hack in years (not since IE6 was the cool browser), so I had to look it up. HowToCreate has a great article on using the IE CSS expression() to overcome fixed-position limitations.
In the end, here is the sample page that I came up with:
<!DOCTYPE HTML>
<html>
<head>
<title>Using CSS Fixed Position Across Browsers</title>
<style type="text/css">
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 ;
}
</style>
<!--
IE-6 Hacks.
NOTE: I am using the "_" hack here because my version of
IE "stand alone" doesn't seem to support conditional
comments: [if lt IE 7.0].
Tip gotten from:
http://www.howtocreate.co.uk/fixedPosition.html
-->
<style type="text/css">
body {
_background-color: gold ;
}
div.fixed-position {
_position: absolute ;
}
div.fixed-n-w,
div.fixed-n,
div.fixed-n-e {
_top: expression( ie6 = (document.documentElement.scrollTop + "px") ) ;
}
div.fixed-e,
div.fixed-w {
_top: expression( ie6 = (document.documentElement.scrollTop + (document.documentElement.clientHeight / 2) + "px") ) ;
}
div.fixed-s-w,
div.fixed-s,
div.fixed-s-e {
_bottom: auto ;
_top: expression( ie6 = (document.documentElement.scrollTop + document.documentElement.clientHeight - 52 + "px") ) ;
}
</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 style="height: 3000px ;">
. <!--- To force scrolling. ---> .
</div>
</body>
</html>
Notice that I am using the underscore "_" hack to run IE6-specific code; I am only using this because my stand-alone version of IE6 does not seem to support conditional comment execution. When you run this in IE6 and scroll around, it's a bit jerky; but, as far as support of outdated browsers goes, it's quite effective.
Here's a screen shot of the above code working in FireFox just so you can see what "position: fixed" does. I tested this in Safari, Chrome, FireFox, IE7, and IE6:
Pretty cool stuff! This also seems like one of the few times where using a negative margin on an element can be quite useful for centered alignment, both horizontally and vertically.
Want to use code from this post? Check out the license.
Reader Comments
That's prob how Facebook does that static menu bar at the bottom of the page :)
@Paolo,
Yeah, I would think so. I think the bottom-bar concept is probably one of the nicest uses of the fixed positioning that I have seen.
Hi Ben, great post :)
What IE6 standalone app are you using?
I use iecollection, which is pretty amazing and *does* work with conditional comments :D
@Dan,
I'm not even sure what version it is. The About menu doesn't help me. I'd love to get a different version - this one doesn't support cookies either, so it's rather limited in what I can use to test.
I have XP, do know if IECollection will install on XP?
It sure does :D
Here is a link to the current version of IECollection: http://finalbuilds.edskes.net/iecollection.htm
Having tested all the alternatives (IETester, MultipleIEs, even running virtual machines with a full version of IE6!) this is definitely the best :)
@Dan,
Awesome! I'll definitely be checking that out. Many thanks.
Interesting, I didn't even realize there was a CSS hack for this! When I have needed fixed positioning for IE6 in the past I used the jQuery Scroll Follow plugin, which also has some additional features like easing effects (http://plugins.jquery.com/project/scroll-follow).
Hey Ben. Awesome stuff. I was wondering why the need for the negative margin. I noticed that if I take it out, it works fine in IE but gets messed up in Firefox. What is the negative margin compensating for?
@Rachel,
I think sometimes the scroll follow effect can be really nice; I think there's room for both techniques for sure.
@Erich,
Basically, if you put top: 50% for a positioned item, then it will be placed just *below* the half way mark (as 50% is the half-way mark and the start of the positioned element). Using a negative top-margin which is *half* the height of the positioned element, will move the middle of the positioned element UP to the half-way mark.
Does that make sense?
Hey Ben, check this out. I'm using fixed positions of PNGs with transparency for a fading effect on content when you scroll:
http://2009.webveteran.com/
Click "about" for a page with more scrollable content.
@Jules,
Very interesting stuff. Neat scrollbar effect.
A much much cleaner way to achieve position: fixed on IE6 and also on all other browsers is:
Remove scrollbar from body and put all body contents inside a wrapper division and make it scroll. Now Put all supposedly position:fixed elements outside this wrapper and give it absolute position.
<body style="overflow: hidden;">
<div style="position:absolute; left:0; top:0">
I am fixed!
</div>
<div style="overflow: auto;">
<!-- your content here -->
</div>
</body>
@Shamasis,
Yeah, I saw that solution when I was searching for an IE fix and I wasn't sure how I felt about it. You also set the HTML / BODY to be height: 100%. It seems nice though, and no jittery effect with scrolling.
I'll have to play with that one. Thanks for making me re-evaluate it.
It is work badly in IE6, css without expression is better solution.
@Minh,
Yeah, I am gonna experiment with the non-expression technique this morning.
I don't support IE6 anymore....made the choice a few months ago. I think it is time to let it go....unless you are designing for the corporate porn seekers. Meaning the "big boy company" that are to lazy to make the change because all their programs only run on old school bits and bites.
Some of the top players on the web are finally making the change to not support IE6 also....like youtube.com. You will see a big push for this type of action in the next few months with the intro to Windows 7.
Not at all people in the world can upgrade to windows 7. You think money is water?
This morning, I tried the alternate, non-Javascript technique. Seems to work quite well:
www.bennadel.com/blog/1735-Using-CSS-Fixed-Position-Elements-Across-Browsers-Without-Javascript.htm
@Minh,
Windows 7 might cost money... but IE7 / IE8 / FireFox / Chrome / Safari / Opera... do not. I don't really see a big issue with starting to turn our backs on IE6.
Re: IE6. There is actually a whole movement towards eliminating it called "IE6 No More", with its own badges you can post on your site too :)
See: http://www.ie6nomore.com/
@Dan and Ben
I recently set up Boot Camp on my iMac at work with Windows XP and SP3. I've consistently rejected the IE8 Windows Update so I can keep IE6 for testing. Seriously, what a pain.
If I do upgrade IE within my Boot Camp installation, I'll definitely give IECollection a whirl.
@Paolo
That site reminds of me of http://www.fixoutlook.org
:)
@Jose,
Yeah, I definitely have to checkout IECollection since I have also rejected IE8 upgrades so I don't lose IE7. Really a super pain!
I have multiple VM's available on my Mac. I have a Win 2K VM with IE6. I have a Win XP VM with IE 7 and a Win7 VM with IE8. I develop using Firefox.
Hmmm... the non-expression solution is the only solution that does not jerk! LOLZ. ;) So, if you really need position:fixed and want a professional output, it is the only way to go.
Otherwise, you would need to use delay/animation to cover-up for the jerks!
Oh God... simple talking can be so connotative these days! :P
@Shamasis,
I've been playing around some more with fixed position elements and I might just decide that they are not worth it in IE6. There just seems to be too many hoops to jump through.
Hi Ben,
I have a situation in which I need to have a fixed div that scrolls with the page, but remains within another div (so that it does not overflow into the footer of the site when you get to the bottom)
Do you know of anyway to restrict the fixed div to stop scrolling within another div?
Thanks.
Chris
Hi Chris,
Is this the effect you are looking for?
http://jqueryfordesigners.com/fixed-floating-elements/
Jose
@Jose,
That looks like a good tutorial - thanks for the post. @Chris, I think that is what you are looking for.
Beautiful, thanks for your help guys!
When Microsoft campaigns against IE6 you know it's bad.
http://www.microsoft.com/australia/technet/ie8milk/
@Jose,
Ha ha ha. Half the time, my IE6 doesn't even boot up properly on my machine anymore. It just sits there with it saying, "connecting," forever. What does that even mean?!? IE6!!
this is not working IE
Thanks Ben Nadel,
Work like charm :D
Excellent code i Love it
Thanks
Regards,
Vishal
@Chris
Here's another jQuery plug-in I found today that does the trick you were asking about earlier.
http://blog.echoenduring.com/2010/11/15/freebie-contained-sticky-scroll-jquery-plugin/
@Jose,
If you want something that's been thoroughly debugged in all browsers, it's better to use jQuery UI than a plug-in:
http://jqueryui.com/demos/position/
One of the options is positioning relative to the window.
As far as I can tell, you don't need to adopt the whole nine yards of jQuery UI just to use the position widget.
Dear Ben
You continue to amaze me, you know.
Only in one of your posts I had commented about the copy->paste->style of learning techniques and here I find you having implemented it already.
I wish I read your posts at least few months back.
I could have saved lots of pains then :)
I am going to bookmark your site and then whenever I launch my site I am going to make a link to your site.
You are a great tutor and I will want my visitors to have painless learning from a tutor like you.
Thanks again and keep the great things going.
Another great post.
Thanks.
I realize that this code is a few years old now, but as far as I can tell it no longer works in IE 9. It however still seems to work perfectly with Firefox 16. Please look into it and let me know if I am doing something wrong, or if their is some other solution.
Thanks in advance!
Well, wish I could just delete that last post, but maybe this will help somebody. It is working fine in IE9. The problem was with how I saved your code. I used the "Download code as text file" option and it inserted a "Blog Entry" comment BEFORE the <!DOCTYPE HTML> tag which completely broke the positioning in IE. After I moved the DOCTYPE back to the top it work just fine.
Along with the HTML code we can use the CSS files. Cascading Style Sheets allow the developers to specify a style to each page. Each page should have a unique characteristics. For creating this unique feature we can use the CSS styles. Now we are using the CSS5.