Using CSS Fixed Position Elements Across Browsers

Posted October 15, 2009 at 10:08 AM

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:

 Launch code in new window » Download code as text file »

  • <!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.

Download Code Snippet ZIP File

Post Comment  |  Ask Ben  |  Other Searches  |  Print Page




Learning ColdFusion 9 - ColdFusion 9 tutorials, samples, examples, demos

Reader Comments

Oct 15, 2009 at 10:17 AM // reply »
5 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 »
7,572 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 »
7,572 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 »
7,572 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 »
7,572 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 »
10 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 »
7,572 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 »
7,572 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 »
7,572 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 »
7,572 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 »
5 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 »
30 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 »
7,572 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 »
31 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 »
7,572 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 »
2 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 »
30 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 »
7,572 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 »
2 Comments

Beautiful, thanks for your help guys!


Post Comment  |  Ask Ben

Recent Blog Comments
Mar 21, 2010 at 11:13 AM
A New Wrist Pain
@chiropractor suwanee, Spoken like someone trying to sell something. Other than for minor, temporary relief from some back pain, chiropractic treatment is nothing but placebo effect and quackery. ... read »
Mar 21, 2010 at 6:32 AM
ColdFusion CFPOP - My First Look
Apologies... The field name in the db for C. is "BounceCode" It stores the code / message which is returned in the email. Sorry for the confusion. ... read »
Mar 21, 2010 at 6:29 AM
ColdFusion CFPOP - My First Look
@Jose Galdamez, Hi Ben and Jose 1st of all.. big thanks to Jose for his Skype chat a few weeks back. Your time was much appreciated. I have come up with a rather unelegant solution to my problem a ... read »
Mar 21, 2010 at 3:42 AM
A New Wrist Pain
Chiropractic treatment is one of the best methods for treating numerous health problems naturally. After years of experience being a chiropractor, I have found that it is a powerful way to solve many ... read »
Mar 20, 2010 at 12:07 PM
Drawing On The iPhone Canvas With jQuery And ColdFusion
Simply awesome. Saved my day. ... read »
Mar 20, 2010 at 9:00 AM
Building A Fixed-Position Bottom Menu Bar (ala FaceBook)
I would like to say thx for an easy way to create a bottom bar. I do have a ?. Is it possible to center the bar if i want to resize it to ex 85%. Regards Offenbach ... read »
Mar 19, 2010 at 7:26 PM
MySQL 3/4 - com.mysql.jdbc.Driver And allowMultiQueries=true
Thank you very much for this post. Adding allowMultiQueries="true" in context.xml didn't help until I added it to url as allowMultiQueries=true Good idea is to use prepared statements and it will he ... read »
Jim
Mar 19, 2010 at 4:49 PM
Nobody Puts Baby In The Corner!
Wow. This is like suddenly finding a support group for your secret shame. I'm not alone! I always liked this movie, even though it is extremely cheesy. I just wish Jennifer Grey hadn't gotten the ... read »