Ben Nadel
On User Experience (UX) Design, JavaScript, ColdFusion, Node.js, Life, and Love.
I am the chief technical officer at InVision App, Inc - a prototyping and collaboration platform for designers, built by designers. I also rock out in JavaScript and ColdFusion 24x7.
Meanwhile on Twitter
Loading latest tweet...
Ben Nadel at cf.Objective() 2011 (Minneapolis, MN) with:

Using CSS Fixed Position Elements Across Browsers Without Javascript

By Ben Nadel on
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

Nice article.
I want to add important note about this usage.
If !Doctype is not used, position:fixed doesn't work on Internet Explorer.

Reply to this Comment

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.

Reply to this Comment

@Anil,

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

Reply to this Comment

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.

Reply to this Comment

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

Reply to this Comment

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

Reply to this Comment

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

Reply to this Comment

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

Reply to this Comment

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

Reply to this Comment

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

Reply to this Comment

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

Reply to this Comment

Post A Comment

You — Get Out Of My Dreams, Get Into My Comments
Live in the Now
Oops!
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.