Using CSS Fixed Position Elements Across Browsers Without Javascript

Posted October 16, 2009 at 9:34 AM by Ben Nadel

Tags: HTML / CSS

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:

 
 
 
 
 
 
Creating Fixed-Position Elements Across All Browsers Using A Sub-Content Container And Absolutely Position Elements. 
 
 
 

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:

 
 
 
 
 
 
Creating Fixed-Position Elements In IE6 Without Any Jittery Effect Using Pure CSS. 
 
 
 

And, since this solution does not use any proprietary IE-based Javascript expressions, scrolling around the window does not lead to any jittering.




Reader Comments

Oct 17, 2009 at 8:30 AM // reply »
2 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.


Oct 17, 2009 at 2:41 PM // reply »
1 Comments

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.


Oct 31, 2009 at 5:00 PM // reply »
11,243 Comments

@Memiso,

I hope people are *always* using doctypes.

@Oleg,

Thanks, I'll take a look.


Nov 3, 2009 at 2:55 AM // reply »
1 Comments

Doctype really cause lot's of issue with IE6


Nov 11, 2009 at 6:16 AM // reply »
2 Comments

Is there any ways to disable scroll bar, because it is unnecessary.


Nov 15, 2009 at 8:06 PM // reply »
11,243 Comments

@Anil,

I am not sure you can remove them when not necessary. I know you can add them when not necessary.


Mar 27, 2010 at 2:46 AM // reply »
1 Comments

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.


Apr 21, 2010 at 10:18 AM // reply »
11,243 Comments

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


Nov 26, 2010 at 1:36 PM // reply »
1 Comments

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


Nov 28, 2010 at 9:04 PM // reply »
11,243 Comments

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


Feb 15, 2011 at 4:55 PM // reply »
1 Comments

Do you have a fix for IE8? It's not scrolling properly, and I cannot figure it out.


Feb 3, 2012 at 11:57 AM // reply »
1 Comments

  • page2 {
  • <body> // page2
  • <?
  • $page1 = "example.extension"
  • ?>
  •  
  • <iframe src="<? $page1 ?>">
  • </body
  •  
  • // page1 = example.extension
  • <body>
  • < a href="#something" rel="jswindow" >something </ a>
  • </body>
  • }

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?


Apr 11, 2012 at 8:51 PM // reply »
1 Comments

MEMISO: You saved my life on this with the !DOCTYPE point. Thank you!!


Dec 6, 2012 at 1:35 AM // reply »
1 Comments

Terrific! I easily place fixed position at every corner but found problem in centering. Sure this great article kill my headache. Good Job!


Apr 16, 2013 at 10:06 PM // reply »
1 Comments

Can anyone tell me, how to make a widget sticky using the same concept?



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 23, 2013 at 9:55 AM
Strange Interaction Between DeserializeJson(), ArrayContains(), And Database Values In ColdFusion
@Dan, According to the CF Admin, I'm running Java "1.6.0_45". As far as the DB column, in the database it's an INT. I'll see if I can dig into what CF sees it as. @WebManWalking, But h ... read »
May 23, 2013 at 9:49 AM
Strange Interaction Between DeserializeJson(), ArrayContains(), And Database Values In ColdFusion
@Ben, I think the problem is that we're used to loose typing in ColdFusion, like JavaScript. If a value is a number but it's needed in an expression to be a string, noooo problem. I've encountered ... read »
May 23, 2013 at 9:47 AM
ColdFusion QueryAppend( qOne, qTwo )
You rock! Thank you, thank you, thank you!!! ... read »
May 23, 2013 at 5:19 AM
Ask Ben: Print Part Of A Web Page With jQuery
How to print also the background color of table cells and table lines ... read »
May 23, 2013 at 3:55 AM
Javascript Array Methods: Unshift(), Shift(), Push(), And Pop()
very interesting and helpful too. ... read »
May 22, 2013 at 5:35 PM
Script Tags, jQuery, And Html(), Text() And Contents()
This is still an issue 2 years later. jQuery is supposed to remediate these cross browser issues, no? I have been unable to find any statement from the jQuery team calling this behavior "by de ... read »
May 22, 2013 at 12:44 PM
Ask Ben: Query Loop Inside CFScript Tags
In cf10, if you call a function that has: local.result = {}; local.result.msg = ""; local.svc = new query(); local.svc.setSQL("SELECT * FROM..."); local.obj = local.svc.exe ... read »
May 22, 2013 at 12:29 PM
Strange Interaction Between DeserializeJson(), ArrayContains(), And Database Values In ColdFusion
@Ben: What version of Java are you using? Also, did you test users.id to see what Java reports as the data type? I wonder if it's not a Java primitive data type, but getting returned as something ... read »
InVision App - Prototyping Made Beautiful With Prototyping Tools