Floating Layer

With CSS 2 specification, a new value fixed for attribute position of a layer can be specified (see this). With position:fixed, the layer stays fixed at the specified position, whereas rest of the page can be scrolled up and down, thus the contents of the layer are always visible. Such a layer is often referred to as a floating layer.This is very useful while displaying site-navigation menu, company logo and so on. You can see one such usage on this page itself.

However, this position:fixed is not yet (as of Jan 2002) supported by some browsers including IE 6 (IE has the largest market share). The browsers which support position:fixed are Netscape 6.1 and Opera 5.x, and they could very easily render a floating layer using this style. Whereas, other browsers including IE and Netscape 4.x, require more programming using CSS and JavaScript to have the same effect. (Well, almost same effect!)

Cross Browser Solution

Cross browser solution involves positioning a layer absolutely, and then repositioning it either on onScroll event which is supported by only IE (AFAIK), or repositioning it using timer. The code given here combines both the solutions and uses the appropriate one depending on the browser.

The code below considers five typical positions where a floating layer can be positioned and repositioned on scrolling.
  1. Top Left
  2. Top Right
  3. Bottom Left
  4. Bottom Right
  5. Center
CSS Part

The CSS part only includes defining a layer class or ID which is absolutely positioned with required height and width. Since the layer floats over rest of the text, it must have a high z-index as well. Optionally, it may also include other attributes such as background color, color, font etc, as it can be defined for any other block level element.

	 /* This must be in <head> and </head> part of the HTML. */
	 
<style type="text/css">
<!--
     .floating {position:absolute; height:70px; width:40px; top:1; visibility:visible; z-index:999;}
-->
</style>

JavaScript Code

This is the major part of floating layer code, this includes positioning the layer at one of the 5 positions initially, and then repositioning it as and when required so that it stays at the same position after scrolling. IE and Netscape both have different DOMs, as a result the way they handle a document page differs significantly, hence detection and branching of code is essential. In your code, once you decide where you want to position your floating layer, ( say, bottom right hand corner for an example.) you can omit the JavaScript code for other 4 positions from positionFloat() function, so your actual JavaScript code will be much smaller and will contain only one case each for IE and Netscape; of course, without the switch-case construct.

<script type="text/javascript">
<!--

var timer = null;
var floatHeight  = 70 + 3; //added margin
var floatWidth   = 40 + 3; //added margin

var obj = null;
var IE=0, NS=0;

	// Initializing function, must be called on onLoad event in BODY tag

function init()
{
    	 // get the object as per the browser
    obj = document.layers ? document.layers["float"] :		 
    document.getElementById ?  document.getElementById("float").style :
    document.all["float"].style;
								
         // Detect the browser
    IE  = (-1 != navigator.appVersion.indexOf("MSIE")) ? 1 : 0;
    NS  = ("Netscape" == navigator.appName) ? 1 : 0;

    positionFloat(4); 	 // position initially
    
         // repositioning the layer	
    if(IE)
    { 
         self.onscroll = function(){ positionFloat(4); }
         self.onresize = function(){ positionFloat(4); }   //when window is resized
    }
    else if(NS)
    { timer = setInterval("positionFloat(4)",100);}
}
 
	// Function which actually positions the layer 	

function positionFloat(iPos)
{
   if(IE)          // IE specific code
   {
     switch(iPos)
     {
   	case 1 :  			// Top Left
      		obj.left = document.body.scrollLeft;
      		obj.top =  document.body.scrollTop;
      		break;
   	case 2 :  			// Top Right
      		obj.left = document.body.scrollLeft + document.body.clientWidth  - floatWidth;;
      		obj.top =  document.body.scrollTop;
      		break;
   	case 3 :  			// Bottom Left
      		obj.left = document.body.scrollLeft;
      		obj.top =  document.body.scrollTop + document.body.clientHeight  - floatHeight;
      		break;
   	case 4 :  			//Bottom Right
      		obj.left = document.body.scrollLeft + document.body.clientWidth  - floatWidth;
      		obj.top =  document.body.scrollTop + document.body.clientHeight  - floatHeight;
      		break;
   	case 5 :  	   		// CENTER
      		obj.left = document.body.scrollLeft + Math.floor((document.body.clientWidth/2) - (floatWidth/2));
      		obj.top =  document.body.scrollTop + Math.floor((document.body.clientHeight/2) - (floatHeight/2));
      		break;
     }
   }
   else if(NS)     // Netscape specific code
   {
     switch(iPos)
     {
   	case 1 :  			// Top Left
      		obj.left = self.pageXOffset;
    		obj.top =  self.pageYOffset;
      		break;
   	case 2 :  			// Top Right
      		obj.left =  self.pageXOffset + self.innerWidth - floatWidth - 15;
    		obj.top =  self.pageYOffset ;
      		break;
   	case 3 :  			// Bottom Left
      		obj.left =  self.pageXOffset;
    		obj.top =  self.pageYOffset  + self.innerHeight - floatHeight;
      		break;
   	case 4 :  			//Bottom Right
      		obj.left =  self.pageXOffset + self.innerWidth - floatWidth - 15;
    		obj.top =  self.pageYOffset  + self.innerHeight - floatHeight;
      		break;
   	case 5 :  	   		// CENTER
      		obj.left =  self.pageXOffset + Math.floor((self.innerWidth/2) - (floatWidth/2) - 15);
      		obj.top =  self.pageYOffset  + Math.floor((self.innerHeight/2) - (floatHeight));
      		break;
     }
   }
}
// -->
</script>

The Floating Layer & Its Contents

A floating layer can have all the contents that any other normal layer or block level element would contain. This layer could be anywhere in the BODY of the HTML document, and it should be assigned the class defined in the CSS, and some ID.
Also, you must call the init() function on "onLoad" event of the BODY tag of your HTML document to position this layer, and kill the timer conditionally on the "onUnload" event of the same tag. (Conditionally because, IE will not use the timer.)

<BODY onLoad="init();" onUnload="if(null != timer)clearInterval(timer);">

<div class="floating" ID="float">
        <!-- You can put anything here -->
   <a href="#top"><img src="images/top.gif" border="0" height="70" width="40"></a>		
</div>

No big deal, right?
The layer in this code contains an image which is shown in the bottom right hand corner of this page, clicking on the image will take you to the top of this page. In your code, you'll need to modify height and width of this layer as per the contents you put in it.
With little imagination and a bit of experimentation, this code can be used for various purposes, and the resulting effect will be really cool, so happy coding and debugging ;))

A little Note

The code self.onresize = function(){ positionFloat(4); } is required in case of IE because, without this code the the floating layer *will not* get repositioned on resizing until you scroll again. As you'll notice , in case of Internet Explorer (IE), the repositioning takes place on "onScroll" event (which is not supported in Netscape yet, AFAIK).
However, in case of Netscape the repositioning happens on a time interval of 100 ms, hence you can see the layer getting repositioned almost immediately after resizing. Thanks to Robert Gelb for writing in, which prompted me to include this note.

Also, I have recently tested and noticed that Netscape specific code also works for Opera 5.x, so you can simply change "else if(NS)" part to a suitable condition (such as "else", if you please) to make it work with Opera.
Author: Manish Hatwalne