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: Barney Boisvert

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.

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.

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.

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

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

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

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

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

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

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