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.
- Top Left
- Top Right
- Bottom Left
- Bottom Right
- 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