Click to See Complete Forum and Search --> : Fixing a menu to the top in IE
nataliemac
06-05-2006, 03:13 PM
I'm building the front end of a web application that has a navigation bar and a subnavigation bar across the top of the screen. I really need these to be fixed at the top of the screen. No problem in FF, but of course IE is another story all together.
I'm using a conditional IE stylesheet to try and get it working.
Here's my IE-only CSS so far:
html,
body {
height: 100%;
overflow: hidden;
width: auto;
}
div#MainDiv {
padding: 0;
margin: 0;
height: 100%;
width: 100%;
overflow: auto;
position: relative;
z-index: 700;
}
#navcontainer {
background-color: #CABBAF;
border-top: 1px solid #14100D;
display: block;
padding: 0.5em 0.5em 0 0.5em;
position: absolute;
top: 0;
left: 0;
height: 1.5em;
z-index: 900;
}
#navcontainersub {
background: #745F4E;
position: absolute;
left: 0;
top: 3.2em;
height: 1.5em;
z-index: 800;
padding: 0;
padding-top: 0.1em;
}
And my [abbreviated] HTML:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
<title>Equipment Search</title>
<link rel="stylesheet" href="../StyleSheets/train.css" type="text/css" />
<!--[if IE]>
<link rel="stylesheet" href="../StyleSheets/ie6fixed.css" type="text/css" />
<![endif]-->
</head>
<body>
<div id="navcontainer">
<ul>
<li>Item 1</li>
<li>Item 2</li>
<li>Item 3</li>
<li>Item 4</li>
</ul>
</div>
<div id="navcontainersub">
<a href="#" class="button">Save</a>
<a href="#" class="button">Close</a>
</div>
<div id="MainDiv">
<!-- All page content -->
</div>
</body>
</html>
Two main problems I'm having:
1. The MainDiv should have some nice padding on either side (in FF, it's set to 95% width), but the scrollbar should still be flush to right side of the window. When I try to set MainDiv to 100% width with 2.5% padding on left and right, it comes out all crazy. (Crazy = 2.5% padding on the left, with the MainDiv apparently still 100% of the window width, so shifted over so that it goes off the screen on the right with no scrollbars at all.) What's an alternative?
2. How can I get the MainDiv to start below my navigation bars, but still fill the rest of the window from top to bottom? Or at least come close?
Thanks,
Natalie
Oh, and since it's a web app and not a site, it only has to work in IE 6+ and FF 1.5+. We know that those are the only two browsers our users are using.
nataliemac
06-05-2006, 03:28 PM
Okay, I solved the first problem. I had to set the left-right padding to 2.5%, then also set the width to 95%. Brother.
Still stumped on how to get the MainDiv to start below the navigation bars. Applying a top margin seems to have no effect at all.
Hmmm...
nataliemac
06-05-2006, 08:58 PM
Okay, this code seems to fix my layout, and is reasonably close to making MainDiv as tall as the window from the bottom of the navigation bars to the bottom of the screen, even with some reasonable re-sizing.
div#MainDiv {
padding: 0 2.5%;
margin: 0;
height: 85%;
width: 95%;
overflow: auto;
position: relative;
top: 6em;
z-index: 700;
}
Now, could someone please explain to me why all of the relatively positioned elements contained *within* the MainDiv either don't show up at all or show up absurdly out of place? And, most importantly, how do I go about fixing them?
RARRRRRR
nataliemac
06-06-2006, 04:37 PM
Just sharing my learning experience at this point, I guess, since nobody's jumping in to help...
Turns out that this
html,
body {
height: 100%;
overflow: hidden;
width: auto;
}
CSS hack for IE will indeed allow you to fake fixed positioning. It also, however, prevents the use of position:absolute and position:relative anywhere on the page. Hmph.
Fine and dandy for simple layouts I suppose but not at all helpful for applications with lots of carefully positioned and dynamic page elements. So I am still searching for a solution.
I have tried:
* Some brief experiments with IE-only JavaScript to fake fixed positioning of the menus
* Throwing IE into quirks mode on purpose to use CSS expressions for positioning. (Fixed the menus, but naturally would require a complete re-write of thousands of lines of CSS)
Any other suggestions?
Please?
8 hours on this and counting. But at least it's billable time, right? ;)
toicontien
06-06-2006, 09:33 PM
You can give an element relative positioning, and then any tags it contains can be positioned absolutely or relatively in respect to the parent tag. The link in my signature entitled "Quick positioning explanation" gives a good primer on this. You may also be interested in CSS "frames" http://www.cssplay.co.uk/menu/framed.html
nataliemac
06-07-2006, 12:51 PM
You can give an element relative positioning, and then any tags it contains can be positioned absolutely or relatively in respect to the parent tag. The link in my signature entitled "Quick positioning explanation" gives a good primer on this.
Yes, ideally. But apparently there is something about using
html,
body {
height: 100%;
overflow: hidden;
width: auto;
}
that makes it impossible to use relative positioning. I'm not sure that I understand why, but in my Google searches I came across it again and again, that assigning that code to the body allowed you to fake fixed positioning in IE, but that you sacrificed relative positioning and absolute positioning throughout the rest of your document. I understand the absolute positioning as anything that is absolute now becomes "fixed". But why the relative? I don't know, but I can assure you that these people are right. My layout is dog's dinner.
And what's more - as you move your mouse around the screen, various elements (with no :hover or onmouseover events) jump several pixels up and down or left and right as though IE can't make up its mind where to place things.
You may also be interested in CSS "frames" http://www.cssplay.co.uk/menu/framed.html
Thank you. I've looked at and tested a variety of approaches to CSS "frames" but so far they haven't worked out. I'll take a look at these and see if I can find my solution in there.
--Natalie
toicontien
06-07-2006, 01:28 PM
The following code works for me in Firefox and Internet Explorer-Win. The nav bar at the top remains at the top as you scroll in both browsers:
<?xml version="1.0"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
<title>Equipment Search</title>
<style type="text/css" media="screen">
<!--
body {
margin: 0;
padding: 0;
}
#MainDiv {
background-color: #cfc;
margin-top: 4em;
}
#navcontainer {
background-color: #fcc;
left: 0;
line-height: 1.5em;
position: fixed;
top: 0;
width: 100%;
}
#navcontainer li {
float: left;
}
#navcontainer #navcontainersub {
clear: left;
}
#navcontainer ul {
list-style-type: none;
margin: 0;
padding: 0;
}
.spacer {
clear: both;
font-size: 1px;
height: 1px;
overflow: hidden;
}
-->
</style>
<!--[if IE]>
<style type="text/css" media="screen">
body {
height: 100%;
padding-top: 4em;
overflow: hidden;
width: 100%;
}
#fixIE {
background-color: #ccf;
height: 100%;
overflow: auto;
width: 100%;
}
#MainDiv {
margin-top: 0;
}
#navcontainer {
position: absolute;
}
</style>
<![endif]-->
</head>
<body>
<div id="navcontainer">
<ul>
<li>Item 1</li>
<li>Item 2</li>
<li>Item 3</li>
<li>Item 4</li>
</ul>
<ul id="navcontainersub">
<li><a href="#" class="button">Save</a></li>
<li><a href="#" class="button">Close</a></li>
</ul>
<div class="spacer"> </div>
</div>
<div id="fixIE">
<div id="MainDiv">
All page content
<br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br />
All page content
<br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br />
All page content
<br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br />
All page content
<br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br />
All page content
<br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br />
All page content
<br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br />
All page content
<br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br />
All page content
<br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br />
All page content
<br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br />
All page content
</div><!-- end MainDiv -->
</div><!-- end fixIE -->
</body>
</html>
Note that the only way to get this to work in IE-Win is to keep the XML Prolog at the top before the DTD tag. This throws IE-Win, up to version 6, into Quirks Mode where it interprets the box model like IE5 (width includes border and padding).
nataliemac
06-07-2006, 02:07 PM
Note that the only way to get this to work in IE-Win is to keep the XML Prolog at the top before the DTD tag. This throws IE-Win, up to version 6, into Quirks Mode where it interprets the box model like IE5 (width includes border and padding).
The problem with throwing IE into quirks mode is that my layout is still dog's dinner - it's a rather complex layout that relies a great deal on IE's standards-compliant mode box model. :( I had tried that and was so discouraged at the thought of adding hundreds of lines to my IE-only stylesheet that I quickly removed the prolog and banished the thought of quirks mode.
Although if that's the way I have to go, then I guess it's better to know that now when we've only built one module of our software instead of later when I'd have to re-layout all four modules.
<sigh>
I am determined to do this - damn IE and your lack of fixed positioning! - I also have (at client's request) over-ridden the window.alert method with a function that produces a custom-designed <div> that also relies on IE being able to reproduce something akin to fixed positioning, so there are really two problems to be resolved by this one issue.
toicontien
06-08-2006, 01:33 PM
The problem with throwing IE into quirks mode is that my layout is still dog's dinner - it's a rather complex layout that relies a great deal on IE's standards-compliant mode box model.
HA HA HA! Even in standards mode, it's box model isn't standards compliant :p That aside, it's easy to fake it without CSS hacks.
<div id="some_column_or_box">
<div class="gutter">
content goes here
</div>
</div>
Then in your CSS:
/* Place borders and/or padding here, but no width */
.gutter {
border: 1px solid #000;
padding: 0 12px;
}
/*
* Set the width of the box here, but don't use borders or padding.
* Margins are OK.
*/
#some_column_or_box {
float: left;
width: 200px;
}
:( I had tried that and was so discouraged at the thought of adding hundreds of lines to my IE-only stylesheet that I quickly removed the prolog and banished the thought of quirks mode.
Don't give up yet. Then IE-Win has won :D
Although if that's the way I have to go, then I guess it's better to know that now when we've only built one module of our software instead of later when I'd have to re-layout all four modules.
Believe me, Natalie. I know your pain. It's a confusing, spitefull, frustrating, hopeless kind of feeling. Like being tied to train tracks and accepting your impending death while the train is only 10 feet away.
<sigh>
Now you've accepted it. Squish.
I am determined to do this - damn IE and your lack of fixed positioning!
SHAKE YOUR FISTS HARDER!
I also have (at client's request) over-ridden the window.alert method with a function that produces a custom-designed <div> that also relies on IE being able to reproduce something akin to fixed positioning, so there are really two problems to be resolved by this one issue.
Hm. This might not be so unsolvable. If you call the new alert method after an onclick, mousedown, mouseover, or some other standard event, all browsers create an event object. You can use the event object to detect the edges of the user's screen and position the DIV on-the-fly. Some example code is below:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<html>
<head>
<title>Page title</title>
</head>
<body>
<input class="button" type="button" id="clickBtn" value="Click me!">
<script type="text/javascript">
<!-- begin hiding
var temp = document.getElementById("clickBtn");
temp.onclick = function(e) {
if (e == "undefined" || e == null) { e = window.event; }
alert(e);
}
// end hiding -->
</script>
</body>
</html>
Now, just look up window.event or window event on google. I think quirksmode.org has a good article about it.