Using CSS Fixed Position Elements Across Browsers

Posted October 15, 2009 at 10:08 AM by Ben Nadel

Tags: Javascript / DHTML, HTML / CSS

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:

 
 
 
 
 
 
Using CSS Position: Fixed To Create Fixed Position Elements Across Browsers. 
 
 
 

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.




Reader Comments

Oct 15, 2009 at 10:17 AM // reply »
21 Comments

That's prob how Facebook does that static menu bar at the bottom of the page :)


Oct 15, 2009 at 10:19 AM // reply »
11,246 Comments

@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.


Oct 15, 2009 at 10:22 AM // reply »
2 Comments

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


Oct 15, 2009 at 10:24 AM // reply »
11,246 Comments

@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?


Oct 15, 2009 at 10:43 AM // reply »
2 Comments

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 :)


Oct 15, 2009 at 10:48 AM // reply »
11,246 Comments

@Dan,

Awesome! I'll definitely be checking that out. Many thanks.


Oct 15, 2009 at 10:56 AM // reply »
4 Comments

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).


Oct 15, 2009 at 11:08 AM // reply »
1 Comments

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?


Oct 15, 2009 at 11:11 AM // reply »
11,246 Comments

@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?


Oct 15, 2009 at 1:49 PM // reply »
12 Comments

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.


Oct 15, 2009 at 1:52 PM // reply »
11,246 Comments

@Jules,

Very interesting stuff. Neat scrollbar effect.


Oct 15, 2009 at 4:43 PM // reply »
2 Comments

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>


Oct 15, 2009 at 5:12 PM // reply »
11,246 Comments

@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.


Oct 16, 2009 at 5:50 AM // reply »
2 Comments

It is work badly in IE6, css without expression is better solution.


Oct 16, 2009 at 8:06 AM // reply »
11,246 Comments

@Minh,

Yeah, I am gonna experiment with the non-expression technique this morning.


Oct 16, 2009 at 9:12 AM // reply »
1 Comments

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.


Oct 16, 2009 at 9:21 AM // reply »
2 Comments

Not at all people in the world can upgrade to windows 7. You think money is water?


Oct 16, 2009 at 9:46 AM // reply »
11,246 Comments

This morning, I tried the alternate, non-Javascript technique. Seems to work quite well:

http://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.


Oct 16, 2009 at 9:51 AM // reply »
21 Comments

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/


Oct 16, 2009 at 10:55 AM // reply »
44 Comments

@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

:)


Oct 16, 2009 at 10:58 AM // reply »
11,246 Comments

@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!


Oct 16, 2009 at 11:32 AM // reply »
40 Comments

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.


Oct 16, 2009 at 1:30 PM // reply »
2 Comments

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


Oct 31, 2009 at 4:59 PM // reply »
11,246 Comments

@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.


Nov 12, 2009 at 6:25 AM // reply »
4 Comments

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


Nov 12, 2009 at 12:46 PM // reply »
44 Comments

Hi Chris,

Is this the effect you are looking for?

http://jqueryfordesigners.com/fixed-floating-elements/

Jose


Nov 12, 2009 at 12:56 PM // reply »
11,246 Comments

@Jose,

That looks like a good tutorial - thanks for the post. @Chris, I think that is what you are looking for.


Nov 13, 2009 at 10:07 AM // reply »
4 Comments

Beautiful, thanks for your help guys!


May 18, 2010 at 11:33 AM // reply »
44 Comments

When Microsoft campaigns against IE6 you know it's bad.

http://www.microsoft.com/australia/technet/ie8milk/


May 18, 2010 at 8:31 PM // reply »
11,246 Comments

@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!!


ali
Jun 15, 2010 at 5:01 AM // reply »
1 Comments

this is not working IE


Aug 12, 2010 at 3:58 AM // reply »
1 Comments

Thanks Ben Nadel,

Work like charm :D

Excellent code i Love it

Thanks

Regards,
Vishal


Nov 22, 2010 at 2:39 PM // reply »
44 Comments

@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/


Nov 22, 2010 at 6:26 PM // reply »
272 Comments

@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.


Jan 10, 2012 at 10:56 PM // reply »
3 Comments

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.


Feb 16, 2012 at 10:48 AM // reply »
3 Comments

Another great post.
Thanks.


Oct 25, 2012 at 5:57 PM // reply »
2 Comments

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!


Oct 25, 2012 at 6:38 PM // reply »
2 Comments

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.



Post A Comment

Comment Etiquette: Please do not post spam. Please keep the comments on-topic. Please do not post unrelated questions or large chunks of code. And, above all, please be nice to each other - we're trying to have a good conversation here.

Please review the following issues:

Author Name:


Author Email:

Author Website:

Comment:

Supported HTML tags for formatting: <strong>bold</strong>   <em>italic</em>   <code>code</code>







  • Help Wanted - Find Your Next ColdFusion Job
Ben Nadel's Company - Epicenter Consulting Recent Blog Comments
May 25, 2013 at 10:08 AM
Using "//" And ".//" Expressions In XPath XML Search Directives In ColdFusion
@Ben, my question is that i want the current node with its tag and its parent node. i just want only that data. So, give me the solution for that. and remember solution is working on " xpath 1.0 ... read »
May 25, 2013 at 10:01 AM
Using "//" And ".//" Expressions In XPath XML Search Directives In ColdFusion
hey ben, i want get my current node tag and also want the root node tag withing. So, how can i fix it.. ! ... read »
May 24, 2013 at 5:39 PM
Ask Ben: Manually Enforcing Basic HTTP Authorization In ColdFusion
@Adam Oops! My mistake! I hadn't gotten that far in my testing - I'm still baby stepping my way through the process. ... read »
May 24, 2013 at 5:13 PM
Ask Ben: Manually Enforcing Basic HTTP Authorization In ColdFusion
Hi Jason, Thanks for checking up on that, but I still stand firm on my position. :) There are actually two listLast()'s in use, and you're right that the one using a space as a delimiter is fine. ... read »
May 24, 2013 at 4:45 PM
Ask Ben: Manually Enforcing Basic HTTP Authorization In ColdFusion
@Ben I have been lurking your site for quite some time, and haven't stepped up to comment until today. Thanks for all the great info - keep it up! @Adam I believe you are mistaken... as the commen ... read »
May 24, 2013 at 11:21 AM
Strange Interaction Between DeserializeJson(), ArrayContains(), And Database Values In ColdFusion
@WebManWalking, Ha ha, let's us never speak of justifying "##" notation again :P ... read »
May 24, 2013 at 11:18 AM
Strange Interaction Between DeserializeJson(), ArrayContains(), And Database Values In ColdFusion
@Ben, Ah, so it was indeed how I vaguely remembered it to be: A direct assignment value = users.id[ i ] causes value to retain the sticky datatype of the query column. Although unnecessary in ... read »
May 24, 2013 at 9:11 AM
Preventing Links In Standalone iPhone Applications From Opening In Mobile Safari
@Brandon, Hi, No, I haven't been able to do that. I have just kept it as it is. ... read »
InVision App - Prototyping Made Beautiful With Prototyping Tools