...

View Full Version : Position: Fixed; + IE + Horizontal Scrolling.



rlemon
06-01-2005, 09:26 PM
ok, so I have a site with alot of horizontal scrolling (and vertical scrolling but i can get that working so it's not a problem) and I want a 'area' to follow the page when the user scrolls (both horizontally and vertically). The code I have works fine in Mozilla for both horizontal and vertical scrolling however in IE the horizontal scrolling does not work.

My area of code is a button (form element) that can easily be surrounded by a div tag.

I want that button to appear top:100; right: 100; always.

the code i have


<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" >
<head>
<meta http-equiv="Content-Type" content="application/xhtml+xml; charset=UTF-8" />
<title> testing CSS Poisitioning </title>
<style type="text/css">

body {
margin:0;
padding:0 10px 0 10px;
border:0;
height:100%;
overflow-y:auto;
overflow-x:auto;
background:rgb(123,187,221);
}

#page {
margin:10px 10px 10px 10px;
display:block;
width:1500px;
height:1500px;
border:1px solid #000;
background:#fff;
padding:10px;
}
#button {
display:block;
top:100px;
right:100px;
width:100px;
position:fixed;
border:1px solid #888;
padding:10px;
text-align:center;
font-weight:bold;
color:#000;
}
* html #button {position:absolute;}
</style>
<!--[if IE]>
<style type="text/css">
/*<![CDATA[*/
html { overflow-x:auto; overflow-y:hidden; }
/*]]>*/
</style>
<![endif]-->
</head>

<body>
<div id="page">

<div id="button">

DUMMY BUTTON

</div>
</div>
</body>
</html>

traherom
06-02-2005, 12:42 AM
IE doesn't do fixed...

Similar problem here (http://www.codingforums.com/showthread.php?threadid=60172) .

JamieR
06-02-2005, 12:46 AM
I wonder if http://www.stunicholls.myby.co.uk/layouts/fixed.html would be of any use to you. Also, I've never heard of position:fixed, only it's closest match - position:absolute :o

harbingerOTV
06-02-2005, 02:01 AM
looking at rlemons' code and the link weazel gave it looks like he's been there already ;)

if you notice that if you collapse the browser in IE on that page the menu box moves with the horizontal scroll.

I've nmessed around with fixed in IE a bit but never tried what your trying to do. It appears it can't be done without javascript. Vertically no problem but...

you can try this if you want (not CSS but works)


<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" >
<head>
<meta http-equiv="Content-Type" content="application/xhtml+xml;

charset=UTF-8" />
<title> testing CSS Poisitioning </title>
<script type="text/javascript">
// fixed.js: fix fixed positioning and fixed backgrounds in IE/Win
// version 1.8, 08-Aug-2003
// written by Andrew Clover

<and@doxdesk.com>, use freely

/*@cc_on
@if (@_win32 &&

@_jscript_version>4)

var fixed_positions= new Array();
var

fixed_backgrounds= new Array();
var fixed_viewport;

//

Initialisation. Called when the <body> tag arrives. Set up viewport

so the
// rest of the script knows we're going, and add a measurer

div, used to detect
// font size changes and measure image sizes for

backgrounds later

function fixed_init() {
fixed_viewport=

(document.compatMode=='CSS1Compat') ?
document.documentElement :

document.body;
var el= document.createElement('div');


el.setAttribute('id', 'fixed-measure');
el.style.position=

'absolute';
el.style.top= '0'; el.style.left= '0';


el.style.overflow= 'hidden'; el.style.visibility= 'hidden';


el.style.fontSize= 'xx-large'; el.style.height= '5em';


el.style.setExpression('width', 'fixed_measureFont()');


document.body.insertBefore(el, document.body.firstChild);
}

//

Binding. Called every time an element is added to the document,

check it
// for fixed features, if found add to our lists and set

initial props

function fixed_bind(el) {
var needLayout=

false;
var tag= el.tagName.toLowerCase();
var st= el.style;


var cst= el.currentStyle;
var anc;

// find fixed-position

elements
if (cst.position=='fixed') {
needLayout= true;


fixed_positions[fixed_positions.length]= el;
// store original

positioning as we'll overwrite it
st.position= 'absolute';


st.fixedPLeft= cst.left;
st.fixedPTop= cst.top;


st.fixedPRight= cst.right;
st.fixedPBottom= cst.bottom;


st.fixedPWidth= fixed_parseLength(cst.width);
st.fixedPHeight=

fixed_parseLength(cst.height);
// find element that will act as

containing box, for convenience later
st.fixedCB= null;
for

(anc= el; (anc= anc.parentElement).parentElement;) {
if

(anc.currentStyle.position!='static') {
st.fixedCB= anc;


break;
} }
// detect nested fixed positioning (only

ancestor need move)
st.fixedNest= false;
for (anc= el; anc=

anc.parentElement;) {
if (anc.style.fixedNest!=null)


st.fixedNest= true;
break;
}
}

// find

fixed-background elements (not body/html which IE already gets

right)
if (cst.backgroundAttachment=='fixed' && tag!='body' &&

tag!='html') {
needLayout= true;


fixed_backgrounds[fixed_backgrounds.length]= el;
// get

background offset, converting from keyword if necessary


st.fixedBLeft= fixed_parseLength(cst.backgroundPositionX);


st.fixedBTop= fixed_parseLength(cst.backgroundPositionY);
// if

it's a non-zero %age, need to know size of image for layout
if

(st.fixedBLeft[1]=='%' || st.fixedBTop[1]=='%') {


st.fixedBWidth= 0; st.fixedBHeight= 0;
fixed_measureBack(el);


}
}
if (needLayout) fixed_layout();
}

// Layout. On every

window or font size change, recalculate positioning

// Request

re-layout at next free moment
var fixed_delaying= false;
function

fixed_delayout() {
if (fixed_delaying) return;
fixed_delaying=

true;
window.setTimeout(fixed_layout, 0);
}

var fixed_ARBITRARY=

200;

function fixed_layout() {
fixed_delaying= false;
if

(!fixed_viewport) return;
var i, el, st, j, pr, tmp, A= 'auto';


var cb, cbLeft, cbTop, cbRight, cbBottom, oLeft, oTop, oRight,

oBottom;
var vpWidth=fixed_viewport.clientWidth,

vpHeight=fixed_viewport.clientHeight;

// calculate initial

position for fixed-position elements [black magic]
for (i=

fixed_positions.length; i-->0;) {
el= fixed_positions[i]; st=

el.style;
// find positioning of containing block
cb=

st.fixedCB; if (!cb) cb= fixed_viewport;
cbLeft=

fixed_pageLeft(cb); cbTop= fixed_pageTop(cb);
if

(cb!=fixed_viewport) { cbLeft+= cb.clientLeft; cbTop+= cb.clientTop;

}
cbRight= fixed_viewport.clientWidth-cbLeft-cb.clientWidth;


cbBottom= fixed_viewport.clientHeight-cbTop-cb.clientHeight;
//

if size is in %, must recalculate relative to viewport
if

(st.fixedPWidth[1]=='%')
st.width=

Math.round(vpWidth*st.fixedPWidth[0]/100)+'px';
if

(st.fixedPHeight[1]=='%')
st.height=

Math.round(vpHeight*st.fixedPHeight[0]/100)+'px';
// find out

offset values at max size, to account for margins
st.left= A;

st.right= '0'; st.top= A; st.bottom= '0';
oRight=

el.offsetLeft+el.offsetWidth; oBottom=

el.offsetTop+el.offsetHeight;
st.left= '0'; st.right= A; st.top=

'0'; st.bottom= A;
oLeft= el.offsetLeft; oTop= el.offsetTop;


// use this to convert all edges to pixels
st.left= A; st.right=

st.fixedPRight;
st.top= A; st.bottom= st.fixedPBottom;


oRight-= el.offsetLeft+el.offsetWidth;
oBottom-=

el.offsetTop+el.offsetHeight;
st.left= st.fixedPLeft; st.top=

st.fixedPTop;
oLeft= el.offsetLeft-oLeft; oTop=

el.offsetTop-oTop;
// edge positioning fix
if

(st.fixedPWidth[1]==A && st.fixedPLeft!=A && st.fixedPRight!=A) {


tmp= el.offsetLeft; st.left= A; st.width= fixed_ARBITRARY+'px';


tmp= fixed_ARBITRARY+el.offsetLeft-tmp+cbLeft+cbRight;


st.left= st.fixedPLeft; st.width= ((tmp<1)?1:tmp)+'px';
}
if

(st.fixedPHeight[1]==A && st.fixedPTop!=A && st.fixedPBottom!=A) {


tmp= el.offsetTop; st.top= A; st.height= fixed_ARBITRARY+'px';


tmp= fixed_ARBITRARY+el.offsetTop-tmp+cbTop+cbBottom;


st.top= st.fixedPTop; st.height= ((tmp<1)?1:tmp)+'px';
}
//

move all non-auto edges relative to the viewport
st.fixedCLeft=

(st.fixedPLeft=='auto') ? oLeft : oLeft-cbLeft;
st.fixedCTop=

(st.fixedPTop=='auto') ? oTop : oTop-cbTop;
st.fixedCRight=

(st.fixedPRight=='auto') ? oRight : oRight-cbRight;


st.fixedCBottom= (st.fixedPBottom=='auto') ? oBottom :

oBottom-cbBottom;
// remove left-positioning of right-positioned

elements
if (st.fixedPLeft=='auto' && st.fixedPRight!='auto')

st.fixedCLeft= 'auto';
if (st.fixedPTop=='auto' &&

st.fixedPBottom!='auto') st.fixedCTop= 'auto';
}


// calculate

initial positioning of fixed backgrounds
for (i=

fixed_backgrounds.length; i-->0;) {
el= fixed_backgrounds[i];

st= el.style;
tmp= st.fixedBImage;
if (tmp) {
if

(tmp.readyState!='uninitialized') {
st.fixedBWidth=

tmp.offsetWidth;
st.fixedBHeight= tmp.offsetHeight;


st.fixedBImage= window.undefined;
}
}
st.fixedBX=

fixed_length(el, st.fixedBLeft, vpWidth-st.fixedBWidth);


st.fixedBY= fixed_length(el, st.fixedBTop,

vpHeight-st.fixedBHeight);
}

// now call scroll() to set the

positions from the values just calculated
fixed_scroll();
}

//

Scrolling. Offset fixed elements relative to viewport scrollness

var fixed_lastX, fixed_lastY;
var fixed_PATCHDELAY= 300;
var

fixed_patching= false;

// callback function after a scroll, because

incorrect scroll position is
// often reported first go!
function

fixed_patch() {
fixed_patching= false;
var scrollX=

fixed_viewport.scrollLeft, scrollY= fixed_viewport.scrollTop;
if

(scrollX!=fixed_lastX && scrollY!=fixed_lastY) fixed_scroll();
}

function fixed_scroll() {
if (!fixed_viewport) return;
var i,

el, st, viewportX, viewportY;
var scrollX=

fixed_viewport.scrollLeft, scrollY= fixed_viewport.scrollTop;


fixed_lastX= scrollX; fixed_lastY= scrollY;

// move non-nested

fixed-position elements
for (i= fixed_positions.length; i-->0;) {


st= fixed_positions[i].style;
viewportX= (st.fixedNest) ? 0 :

scrollX;
viewportY= (st.fixedNest) ? 0 : scrollY;
if

(st.fixedCLeft!='auto') st.left= (st.fixedCLeft+viewportX)+'px';


if (st.fixedCTop!='auto') st.top= (st.fixedCTop+viewportY)+'px';


viewportX= (st.fixedCB==null || st.fixedCB==fixed_viewport) ? 0 :

viewportX;
viewportY= (st.fixedCB==null ||

st.fixedCB==fixed_viewport) ? 0 : viewportY;
st.right=

(st.fixedCRight-viewportX+1)+'px'; st.right=

(st.fixedCRight-viewportX)+'px';
st.bottom=

(st.fixedCBottom-viewportY+1)+'px'; st.bottom=

(st.fixedCBottom-viewportY)+'px';
}

// align fixed backgrounds

to viewport
for (i= fixed_backgrounds.length; i-->0;) {
el=

fixed_backgrounds[i]; st= el.style;
viewportX= scrollX;


viewportY= scrollY;
while (el.offsetParent) {
viewportX-=

el.offsetLeft+el.clientLeft;
viewportY-= el.offsetTop

+el.clientTop;
el= el.offsetParent;
}


st.backgroundPositionX= (st.fixedBX+viewportX)+'px';


st.backgroundPositionY= (st.fixedBY+viewportY)+'px';
}

// call

back again in a tic
if (!fixed_patching) {
fixed_patching=

true;
window.setTimeout(fixed_patch, fixed_PATCHDELAY);
}
}

// Measurement. Load bg-image into an invisible element on the page,

when
// loaded write the width/height to an element's style for

layout use; detect
// when font size changes

function

fixed_measureBack(el) {
var measure=

document.getElementById('fixed-measure');
var img=

document.createElement('img');
img.setAttribute('src',

fixed_parseURL(el.currentStyle.backgroundImage));


measure.appendChild(img);
el.style.fixedBImage= img;
if

(img.readyState=='uninitialized')


img.attachEvent('onreadystatechange',

fixed_measureBackImage_ready);
}

function

fixed_measureBackImage_ready() {
var img= event.srcElement;
if

(img && img.readyState!='uninitialized') {


img.detachEvent('onreadystatechange',

fixed_measureBackImage_ready);
fixed_layout();
}
}

var

fixed_fontsize= 0;
function fixed_measureFont() {
var fs=

document.getElementById('fixed-measure').offsetHeight;
if

(fixed_fontsize!=fs && fixed_fontsize!=0)
fixed_delayout();


fixed_fontsize= fs;
return '5em';
}

// Utility. General-purpose

functions

// parse url() to get value inside

function

fixed_parseURL(v) {
v= v.substring(4, v.length-1);
if

(v.charAt(0)=='"' && v.charAt(v.length-1)=='"' ||


v.charAt(0)=="'" && v.charAt(v.length-1)=="'")
return

v.substring(1, v.length-1);
else return v;
}

// parse length or

auto or background-position keyword into number and unit

var

fixed_numberChars= '+-0123456789.';
var fixed_ZERO= new Array(0,

'px');
var fixed_50PC= new Array(50, '%');
var fixed_100PC= new

Array(100, '%');
var fixed_AUTO= new Array(0, 'auto');

function

fixed_parseLength(v) {
var num, i;
if (v=='left' || v=='top')

return fixed_ZERO;
if (v=='right' || v=='bottom') return

fixed_100PC;
if (v=='center') return fixed_50PC;
if (v=='auto')

return fixed_AUTO;
i= 0;
while (i<v.length &&

fixed_numberChars.indexOf(v.charAt(i))!=-1)
i++;
num=

parseFloat(v.substring(0, i));
if (num==0) return fixed_ZERO;


else return new Array(num, v.substring(i));
}

// convert parsed

(number, unit) into a number of pixels

function fixed_length(el, l,

full) {
var tmp, x;
if (l[1]=='px') return l[0];
if

(l[1]=='%') return Math.round(full*l[0]/100);
// other units -

measure by setting position; this is rather inefficient
// but

then these units are used for background-position so seldom...


tmp= el.currentStyle.left;
el.style.left= '0';
x=

el.offsetLeft;
el.style.left= l[0]+l[1];
x= el.offsetLeft-x;


el.style.left= tmp;
return x;
}

// convert stupid IE

offsetLeft/Top to page-relative values

function fixed_pageLeft(el)

{
var v= 0;
while (el.offsetParent) {
v+= el.offsetLeft;


el= el.offsetParent;
}
return v;
}
function fixed_pageTop(el) {


var v= 0;
while (el.offsetParent) {
v+= el.offsetTop;
el=

el.offsetParent;
}
return v;
}

// Scanning. Check document

every so often until it has finished loading. Do
// nothing until

<body> arrives, then call main init. Pass any new elements
// found

on each scan to be bound

var fixed_SCANDELAY= 500;

function

fixed_scan() {
if (!document.body) return;
if (!fixed_viewport)

fixed_init();
var el;
for (var i= 0; i<document.all.length; i++)

{
el= document.all[i];
if (!el.fixed_bound) {


el.fixed_bound= true;
fixed_bind(el);
} }
}

var

fixed_scanner;
function fixed_stop() {


window.clearInterval(fixed_scanner);
fixed_scan();
}

fixed_scan();
fixed_scanner= window.setInterval(fixed_scan,

fixed_SCANDELAY);
window.attachEvent('onload', fixed_stop);
window.attachEvent('onresize', fixed_delayout);
window.attachEvent('onscroll', fixed_scroll);

@end @*/

</script>
<style type="text/css">
body {
margin:0;
padding:0 10px 0 10px;
border:0;
background:rgb(123,187,221);
}

#page {
margin:10px 10px 10px 10px;
display:block;
width:1500px;
height:1500px;
border:1px solid #000;
background:#fff;
padding:10px;
}
#scroller {
display:block;
top:100px;
right:100px;
width:100px;
position: fixed;
border:1px solid #888;
padding:10px;
text-align:center;
font-weight:bold;
color:#000;
}
</style>

</head>

<body>
<div id="scroller">

DUMMY BUTTON

</div>
<div id="page">


</div>

</body>
</html>

rlemon
06-02-2005, 03:03 AM
you wouldn't possibly be able to post that as a htm file?
the stupid box made the formatting all messed

harbingerOTV
06-02-2005, 03:36 AM
uploaded (http://home.earthlink.net/~harbingerofthevoid/testing/rlemon2.html)

have to forewarn you that's it's choppy on IE but none the less it does accomplish what your trying to do.

traherom
06-03-2005, 08:05 PM
Fixed positioning is possible in IE... here's an example (http://jfy.homeunix.net/misc/example.html). (check the source: I actually cheated a bit to move the scrollbar down, but it does use fixed positioning.) Note that there is no frames on this page. Also try viewing it on Firefox to see the difference. Both the HTML and CSS pass the w3c's validators.

I yoinked that page from the source of a current project, btw.

_Aerospace_Eng_
06-03-2005, 08:28 PM
IE has to be in quirks mode for the fixed property to even work.

harbingerOTV
06-04-2005, 03:43 PM
Fixed positioning is possible in IE... here's an example (http://jfy.homeunix.net/misc/example.html). (check the source: I actually cheated a bit to move the scrollbar down, but it does use fixed positioning.) Note that there is no frames on this page. Also try viewing it on Firefox to see the difference. Both the HTML and CSS pass the w3c's validators.

I yoinked that page from the source of a current project, btw.

Thats a nice example of vertical scrolling and fixed divs. I think we all agree that that way can be done. The problem as I see it was that rlemon need to to fix the position of a div when there was a horizontal scroll involved.

traherom - I fiddled with your code to make it have to have a horizontal scroll to test it out.



.main_container {
width: 3000px;
}
* html div.main_container {
position: absolute;
overflow: hidden;
top: 0px;
left: 0px;
height: 100%;
width: 3000px;
padding-top: 74px;
padding-left: 141px;
padding-right: 0px;
padding-bottom: 0px;
}


then I shoved the navigation off the side so that you could see wheter or not it worked right.


div.options {
position: fixed;
overflow: hidden;
top: 0px;
margin-left: 300px;
height: 100%;
width: 136px;
padding-top: 71px;
padding-left: 0px;
padding-right: 0px;
padding-bottom: 0px;
border-right: 1px solid #CCCCCC;
background-color: #FFFFFF;
z-index: 4;
}


when you first load up the new code:
moz - :)
ie6 - :)

on vertical scrolling:
moz - :)
ie6 - :)

upon horzontal scrolling:
moz - :)
ie6 - :(

the problem is that your telling the div to site off the right side of the page by x-amount. When it's fixed moz understands that you mean x-amount off the side of the browser window. Ie6 on the other hand translates your request for fixing as x-amount off the right side of the <body>.

traherom
06-04-2005, 04:47 PM
You're right. I didn't read carefully enough. :)

However... try squishing my example page up. You'll see that the main "frame" is the only thing that scrolls. I'm not sure why IE takes all the fancy extra stuff to make it work, but the main thing is that the main div (div.main), has the overflow value set to scroll. You also then have to explicitly set the height and width dimensions to fill the entire space.

To do this, I have a containing div which fills the whole page (height and width 100%) (div.main_contain), but has a padding on the top and left to push the inner div (div.main) to where I want it. The inner div has a height and width of 100%, but the padding prevents it from actually doing that. See the CSS at http://jfy.homeunix.net/includes/normal.css.



EZ Archive Ads Plugin for vBulletin Copyright 2006 Computer Help Forum