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.