Fixed/Absolute scrolling vertical menu

I would like this fixed menu to scroll if the height of the browser window is less than the height of the vertical menu plus footer. Ideally the correct position (fixed or absolute) can be changed if the browser window height is resized, too.

An attempt with jQuery is in the HTML, but it does not work. I do not know how to define/target the elements that need to be compared.

Any help would be appreciated.


<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
    <meta http-equiv="content-type" content="text/html; charset=ISO-8859-1">
    <meta http-equiv="content-language" content="en-us">
    <meta http-equiv="content-style-type" content="text/css">
    <title>Menu eXperiments</title>
    <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.5.1/jquery.min.js"></script>
    <style type="text/css">
html,
body {
    height:100%;
    padding:0px;
    margin:0px;
}
body {
    color:#000;
    font-size:100%;
    font-family:Verdana,sans-serif;
    background-color:#bdf;    /* set the background-color of the browser window here #bdf */
    overflow-y:scroll;
    padding:0;
    margin:0;
}
/* Opera Fix */
body:before {    /* thanks to Maleika (Kohoutec) */
    content:"";
    height:100%;
    float:left;
    width:0;
    margin-top:-32767px;    /* thank you Erik J - negate effect of float */
}
#outer {
    width:988px;
    min-height:100%;
    position:relative;
    margin:-50px auto 0;    /* footer height - this drags the outer 40px up through the top of the monitor */
}
.canvas {
    background-color:#532;    /* overall background-color */
    border-radius:20px;
    padding:15px 15px 15px 156px;
}
#footer {
    height:50px;
    clear:both;
}
#footer p {
    font-size:0.75em;
    font-family:'Trebuchet MS',sans-serif;
    text-align:center;
    padding-top:16px;
    margin:0;
}
h1 {
    height:10px;
    border-top:50px solid #fff;    /* soak up negative margin and allows header to start at top of page */
    font-size:.6em;
    text-align:center;
    visibility:hidden;
    margin:0;
}
.content {
    background-color:#e9e8e4;
    background-image:url('../imgs/newsprint1.jpg');
    background-repeat:repeat;
    background-attachment:scroll;
    border-radius:12px;
    width:769px;             /* 817px wide */
    min-height:600px;
    padding:12px 24px 18px;
}
.frame {
    position:relative;    /* just in case you want to p:a something over the image */
}
#p .frame {
    position:static;      /* permits the menu tab to overlay the border around the poster image */
}
.frame img {
    display:block;
    border-radius:12px;
}

/* Navigation  ( screen: height >= 590px; width >= 988px ) */
.nav {
    list-style-type:none;
    position:fixed;        /* absolute (relative to #outer) */
    left:50%;
    top:22px;              /* auto */
    bottom:auto;           /* 15px */
    padding:0;
    margin:0 0 0 -484px;
}
.nav li {
    display:block;
    width:138px;
    text-align:center;
    font-weight:bold;
    font-size:18px;
    font-family:Verdana,sans-serif;
    padding:0;
    margin:0;
}
.nav li + li {
    margin-top:8px;
}
.nav li.urhere,
.nav li.dummy {
    padding:8px 0;
    width:134px;
}
.nav li.urhere {
    border-top:2px solid #ffd700;
    border-bottom:2px solid #ffd700;
    border-left:2px solid #ffd700;
    border-radius:10px 0 0 10px;
    background-color:#fff;
    color:#000;
    padding-right:10px;
}
.nav li.dummy {
    border:2px solid #865;
    border-radius:9px;
    background-color:#421;
    color:#865;
}
.nav li.p {
    margin-top:12px;
}
.nav li.a.urhere,
.nav li.c.urhere,
.nav li.f.urhere,
.nav li.l.urhere,
.nav li.r.urhere,
.nav li.s.urhere {
    background-color:#e9e8e4;
    background-image:url('../imgs/newsprint1.jpg');
    background-repeat:repeat;
    background-attachment:scroll;
}
.nav li.p.urhere {
    background-color:#88c4e6;
    position:relative;
}
.nav li.p.urhere:after {
    content:"";
    width:4px;
    position:absolute;
    top:0;
    right:-4px;
    bottom:0;
    background-color:#88c4e6;
}
.nav li.i a {
    display:table;
    border:0;
    border-radius:50%;
    padding:2px;
    margin:0 auto;
}
.nav li.i a:active {
    background-color:#f00;
}
.nav a {
    display:block;
    border:2px solid #865;
    border-radius:10px;
    background-color:#421;
    color:#f0f0f0;
    text-decoration:none;
    padding:8px 0;
}
.nav a:link,a:visited {}
.nav a:hover {
    color:#00f;
    border:2px solid #00f;
    background-color:#ccc;
}
.nav a:active {
    color:#f00;
    border:2px solid #f00;
    background-color:#eee;
}
.nav a img {
    display:block;
    border:none;
}
/* IMAGES */
.rogposter {
    border:4px solid #ddb600;    /* #ddb600 */
}
/* */
    </style>
</head>
<body id="p">
<script type="text/javascript">
$(window).scroll(function() {
    if ($(window).scrollTop() >= 900) {    // offset?
        $('.nav').css({'position':'fixed','top':'22px','bottom':'auto'});
    } else {
        $('.nav').css({'position':'absolute','top':'auto','bottom':'15px'});
    }
});
</script>
<div id="outer">
    <h1>Header Text Here</h1>
    <ul class="nav">
        <li class="i"><a href="#"><img src="imgs/RE_Logo128e-.png" alt="" width="128" height="128"></a></li>
        <li class="p urhere">IMAA Rally of Giants 2013 Poster</li>
        <li class="r"><a href="#">Registration</a></li>
        <li class="l"><a href="#">Location</a></li>
        <li class="f"><a href="#">Float Fly</a></li>
        <li class="s"><a href="#">Local Sights</a></li>
        <li class="a"><a href="#">Sponsors &amp; Vendors</a></li>
        <li class="c"><a href="#">Contact Us</a></li>
    </ul>
    <div class="canvas">
        <div class="frame">
            <img class="rogposter" src="imgs/RoGPoster2-.jpg" alt="" width="809" height="700">
        </div>
    </div>
</div>
<div id="footer">
    <p id="datebot">Updated:&nbsp; Sunday, December 02, 2012</p>
</div>
</body>
</html>

Hi Ron,

Try placing your JavaScript directly before the closing </body> tag:

    <script type="text/javascript">
      $(window).scroll(function() {
        if ($(window).scrollTop() >= 900) {    // offset?
          $('.nav').css({'position':'fixed','top':'22px','bottom':'auto'});
        } else {
          $('.nav').css({'position':'absolute','top':'auto','bottom':'15px'});
        }
      });
      </script>
  </body>
</html>

Does that help any?

Hi again,

Just been playing around with this. It kind of breaks when the content area gets too big (I don’t know if that is a likely scenario) or when you resize the browser.
Is this more the kind of effect you are after.

Wow, that was quick, Pullo! Thank you.

I moved the script to the bottom of the page but it makes no difference.

I had already looked at the jQuery page in your second post but it doesn’t fill the bill, either.

The IF part, first line of logic, is all wrong in my “attempt”. The THEN part is good. Let’s see if I can describe the way the IF part is really supposed to work…

IF the bottom of the page is lte ~900px from the top of the window (approx the height of the menu box plus footer),
THEN the menu position should be relative to the bottom of the page (thus allowing the top of the menu to scroll offscreen as the bottom of the page approaches)
ELSE the menu position should be fixed.

The icing on the cake would be IF resizing the browser window happens to cross the breakpoint where either of the conditions above are met, THEN the appropriate position will be set, also.

My description is probably does not target the most reliable method of determining the height of the menu box + footer + header but I think it conveys the idea.

Does this help?

Hi Ron,

Not 100% sure I understand, so let’s take a slightly different approach.

Your page looks like this:

<body>
<div id=“outer”>…</div>
<div id=“footer”>…</div>
</body>

The footer has a fixed height of 50px, whereas outer takes up the rest of the available area, with a minimum height of 798px (to accommodate margins, paddings and its contents).

If the viewport height is less than 798 + 50 = 848px, then horizontal scrolling takes place.

So by this do you mean:

If the viewport height is less than 900px 
  do some stuff
Else
  do some other stuff

No, not the viewport height, but the distance between the top of the browser window (viewport) and the bottom of the body of the web page, which may be hundreds of pixels below the bottom of the browser window or entirely above it.

Here are the possibilities:

(1) IF the viewport is taller than the menu, THEN do nothing. (the menu will always be visible)
(2) IF the viewport is shorter than the menu (part of the menu will be off-screen below the viewport), THEN
(2 a) While the bottom of the page is below the bottom of the menu, THEN do nothing. (menu is still fixed)
(2 b) When the bottom of the page is equal to or above the bottom of the menu, THEN change the menu position to absolute (so the bottom of the menu will scroll into view with the bottom of the page. Top of menu will scroll offscreen top.)

See if this computes:

Normally the menu is fixed.

IF the height of the viewport is shorter than the menu, AND the bottom of the web page is less than or equal to the height of the menu THEN change the menu to absolute.

Yup, thanks, that’s much clearer.
I’m away from the PC at the moment, but I’ll knock you up something later on.

[FONT=Verdana]A little background and some thoughts…

The problem with the menus on the jQuery demo page (and all others that I found) is that they assume the entire menu fits within the height of the viewport. I’m assuming that it may not.

When I first designed this layout, I decided to use a fixed menu because the requirements only indicated three or four menu buttons would be needed. I decided that the fixed layout would be very convenient for the user, and such a menu would fit on a laptop with a 900px high screen. Things have evolved :slight_smile: . The menu is now at it’s maximum designed capacity. If I add one more button, the menu will extend past the bottom of the content area of the page when the page is scrolled to the bottom of the viewport (the button will be visible, but it will be sticking into the footer area). Rather than scrap the fixed menu, I am hoping to make it adapt to a longer menu (one more button, maybe) by scrolling with the bottom of the page.

If it is possible for jQuery to determine the height of the menu box dynamically, then the scheme should be able to adapt to the user’s choice of font size, zoomed text, and to fonts on different platforms; it would auto-adapt if a new menu button were added; and the transition between positions fixed and absolute could be seamless. That would be very slick.

And as I mentioned in the first message, for users like us who resize browser windows just to watch things react, if resizing the height of the window crosses the “breakpoint”, then triggering that position change on resize, too, would be the cat’s meow :slight_smile: .
[/FONT]

Hi Ron,

Here you go:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
    <meta http-equiv="content-type" content="text/html; charset=ISO-8859-1">
    <meta http-equiv="content-language" content="en-us">
    <meta http-equiv="content-style-type" content="text/css">
    <title>Menu eXperiments</title>
    <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.5.1/jquery.min.js"></script>
    <style type="text/css">
html,
body {
    height:100%;
    padding:0px;
    margin:0px;
}
body {
    color:#000;
    font-size:100%;
    font-family:Verdana,sans-serif;
    background-color:#bdf;    /* set the background-color of the browser window here #bdf */
    overflow-y:scroll;
    padding:0;
    margin:0;
}
/* Opera Fix */
body:before {    /* thanks to Maleika (Kohoutec) */
    content:"";
    height:100%;
    float:left;
    width:0;
    margin-top:-32767px;    /* thank you Erik J - negate effect of float */
}
#outer {
    width:988px;
    min-height:100%;
    position:relative;
    margin:-50px auto 0;    /* footer height - this drags the outer 40px up through the top of the monitor */
}
.canvas {
    background-color:#532;    /* overall background-color */
    border-radius:20px;
    padding:15px 15px 15px 156px;
}
#footer {
    height:50px;
    clear:both;
}
#footer p {
    font-size:0.75em;
    font-family:'Trebuchet MS',sans-serif;
    text-align:center;
    padding-top:16px;
    margin:0;
}
h1 {
    height:10px;
    border-top:50px solid #fff;    /* soak up negative margin and allows header to start at top of page */
    font-size:.6em;
    text-align:center;
    visibility:hidden;
    margin:0;
}
.content {
    background-color:#e9e8e4;
    background-image:url('../imgs/newsprint1.jpg');
    background-repeat:repeat;
    background-attachment:scroll;
    border-radius:12px;
    width:769px;             /* 817px wide */
    min-height:600px;
    padding:12px 24px 18px;
}
.frame {
    position:relative;    /* just in case you want to p:a something over the image */
}
#p .frame {
    position:static;      /* permits the menu tab to overlay the border around the poster image */
}
.frame img {
    display:block;
    border-radius:12px;
}

/* Navigation  ( screen: height >= 590px; width >= 988px ) */
.nav {
    list-style-type:none;
    position:fixed;        /* absolute (relative to #outer) */
    left:50%;
    top:22px;              /* auto */
    bottom:auto;           /* 15px */
    padding:0;
    margin:0 0 0 -484px;
}
.nav li {
    display:block;
    width:138px;
    text-align:center;
    font-weight:bold;
    font-size:18px;
    font-family:Verdana,sans-serif;
    padding:0;
    margin:0;
}
.nav li + li {
    margin-top:8px;
}
.nav li.urhere,
.nav li.dummy {
    padding:8px 0;
    width:134px;
}
.nav li.urhere {
    border-top:2px solid #ffd700;
    border-bottom:2px solid #ffd700;
    border-left:2px solid #ffd700;
    border-radius:10px 0 0 10px;
    background-color:#fff;
    color:#000;
    padding-right:10px;
}
.nav li.dummy {
    border:2px solid #865;
    border-radius:9px;
    background-color:#421;
    color:#865;
}
.nav li.p {
    margin-top:12px;
}
.nav li.a.urhere,
.nav li.c.urhere,
.nav li.f.urhere,
.nav li.l.urhere,
.nav li.r.urhere,
.nav li.s.urhere {
    background-color:#e9e8e4;
    background-image:url('../imgs/newsprint1.jpg');
    background-repeat:repeat;
    background-attachment:scroll;
}
.nav li.p.urhere {
    background-color:#88c4e6;
    position:relative;
}
.nav li.p.urhere:after {
    content:"";
    width:4px;
    position:absolute;
    top:0;
    right:-4px;
    bottom:0;
    background-color:#88c4e6;
}
.nav li.i a {
    display:table;
    border:0;
    border-radius:50%;
    padding:2px;
    margin:0 auto;
}
.nav li.i a:active {
    background-color:#f00;
}
.nav a {
    display:block;
    border:2px solid #865;
    border-radius:10px;
    background-color:#421;
    color:#f0f0f0;
    text-decoration:none;
    padding:8px 0;
}
.nav a:link,a:visited {}
.nav a:hover {
    color:#00f;
    border:2px solid #00f;
    background-color:#ccc;
}
.nav a:active {
    color:#f00;
    border:2px solid #f00;
    background-color:#eee;
}
.nav a img {
    display:block;
    border:none;
}
/* IMAGES */
.rogposter {
    border:4px solid #ddb600;    /* #ddb600 */
}

.nav.absolute{
  position: absolute;
  top: auto;
  bottom:15px;
}
/* */
</style>
</head>
<body id="p">
<div id="outer">
    <h1>Rogue Eagles Radio Control Club; Medford, Oregon</h1>
    <ul class="nav">
        <li class="i"><a href="#"><img src="imgs/RE_Logo128e-.png" alt="" width="128" height="128"></a></li>
        <li class="p urhere">IMAA Rally of Giants 2013 Poster</li>
        <li class="r"><a href="#">Registration</a></li>
        <li class="l"><a href="#">Location</a></li>
        <li class="f"><a href="#">Float Fly</a></li>
        <li class="s"><a href="#">Local Sights</a></li>
        <li class="a"><a href="#">Sponsors &amp; Vendors</a></li>
        <li class="c"><a href="#">Contact Us</a></li>
    </ul>
    <div class="canvas">
        <div class="frame">
            <img class="rogposter" src="imgs/RoGPoster2-.jpg" alt="" width="809" height="1700">
        </div>
    </div>
</div>
<div id="footer">
    <p id="datebot">Updated:&nbsp; Sunday, December 02, 2012</p>
</div>

    <script type="text/javascript">
      $(document).ready(function(){
        var $nav = $('.nav'),
            $page = $(document),
            nav_height = $nav.height(),
            frameHeight = $('.frame').height(),
            topOffset = $nav.position().top,
            initialBottomOfNav = topOffset + nav_height,
            initialBottomOfFrame = topOffset + frameHeight;
        
        $(window).scroll(function() {
          var newNavTop = 0,
              frameOutOfView = $page.scrollTop() -  topOffset,
              frameRemaining = frameHeight - frameOutOfView;
          if (frameRemaining <= nav_height){
            $nav.addClass("absolute");
          } else {
            $nav.removeClass("absolute");
          }
        });
      });
    </script>
  </body>
</html>

Demo.

If you have any questions about what I’ve done, just let me know.

Slick, Pullo.

It works perfectly in IE8 and IE9. Exactly as envisioned!

Chrome, Opera, and Firefox have “issues”, though.

Chrome works perfectly if the value of topOffset is changed to 4, otherwise, there is a bit of a jump at the transition point.

Opera draws the menu as position:fixed when one scrolls to the bottom of the page then “refreshes” the browser regardless of the value of topOffset. One must scroll completely to the top of the page and refresh again to reinstate the transition behavior.

Firefox works perfectly if topOffset is 4, otherwise it breaks like Opera except that the transition action can be reinstated by scrolling the bottom of the page below the bottom of the menu (which is off-screen) and then refreshing the browser.

Interesting browser-specific behaviors. I thought jQuery was supposed to minimize stuff like that? DOM-de-DOM-DOM.

If you think the “bugs” are repairable, and you have the time to give it a go, I’d be grateful; otherwise, thank you very much for the proof of concept!

Hi Ron,

I’m glad it works in IE, but I’m afraid I couldn’t reproduce any of your issues with the other browsers.

Let’s focus on Firefox first.
Which FF version are you running and on which OS?

I don’t really think this’ll make a difference, but it’s better if we are both looking at 100% the same thing.

O/S is WinXPPro SP3 32bits of course

Firefox is the latest update… let’s see… 21.0 (Hard to believe that verson 3.6 departed barely 2 years ago. So much progress :rolleyes: ).

Opera/9.80 (Windows NT 5.1) Presto/2.12.388 Version/12.15

Chrome Version 27.0.1453.110 m

I do not run browsers maximized full screen; I use floating windows. (I mention this because you changed the height of img.rogposter from 700px to 1700px while working on the JavaScript.)

Today is Thursday. For those who remember, Thursday is “Anything Can Happen Day”. :slight_smile:

Note: Most tests are performed while the height of the browser window is between roughly 675px and 800px… a range that crosses the transition point.

Today, Chrome still works perfectly IF the topOffset is changed to 4, otherwise it jumps about 20px or so at the transition point.

In Opera, the demo on Hibbard.eu still behaves as described yesterday when the URL is reloaded while scrolled to the bottom of the page, but the copy on another server and with the topOffset changed to 4 is tamer in that the menu position self-corrects if the window is vertically resized or the page is scrolled.

Firefox is flakey. The demo on Hibbard.eu seems to be behaving exactly like Opera did yesterday. A copy on another server and with topOffset changed to 4, behaves differently. If within the transition range of the bottom of the page, reloading the URL usually positions the menu correctly, but not always. Sometimes the menu will be position:fixed, but will self-correct of the window is vertically resized or the page is scrolled. Simply reloading the URL several times will eventually render both positions. If that same file is located on my PC, the behavior is perfect. I don’t exactly trust Firefox.

I realize that if you cannot replicate the behavior I see, then the ball is automatically in my court to find out what’s happening. No probs. It will give me something to read in my spare time. And like I mentioned before, there is always the chance that I might actually learn something! :slight_smile:

If you want to look at the copy of your demo that I have posted on a server, I will send you that URL in a PM. It’s not my server, so I don’t want to publish it. However, the only differences are the change in topOffset and I restored the height reserved for the image to 700px.

Would the JavaScript work more reliably if it were called as an external script or does that matter?

Hi Ron,

Let’s stick with FF at the moment.
I have just set up a VM and installed the 32bit version of WinXP Pro as well as the latest FF.
I also installed a FF add-on to resize my browser window to exactly 1050px x 675px.

Unfortunately, the demo on my server is still behaving as expected.
When I load the page, the menu is fixed in the top left corner of the browser window.
As I scroll down, the menu remains fixed until the bottom of div.frame is level with the bottom of ul.nav (this occurs off-screen).
When this point has been reached, then the menu changes its positioning from fixed to absolute and the bottom of the menu scrolls into view with the bottom of the container.
This is a smooth experience for me and there is no jump.

So, backing up a little:
What happens for you when you do the same thing, using the demo on my server and FF (at a size of 1050px x 675px)?

Also what is the resolution of the monitor you are viewing this on?

It’s Friday here and that is hang out on SPF and don’t get anything done day :slight_smile:

Would the JavaScript work more reliably if it were called as an external script or does that matter?

That makes no difference (but feel free to experiment).
I think that the JS is actually doing what it should and the problem is rather that I have overlooked some factor in this equation.

With a bit of luck we’ll soon get to the bottom of it.

The behavior that I see tonight is the same as I described earlier.

I will try to assemble a collage of screen shots that shows what I see. Should have them ready to post sometime tomorrow.

I’m convinced that the topOffset is part of the problem, but have no knowledge to back that up.

I cannot match the window dimensions exactly. They aren’t that critical anyway. The 700px high image is easier to work with, though… the ~20px jump at the transition point can be more easily demonstrated.

I’ll try to have the image/s ready tomorrow.

I’m at a loss for another way to go.

Thanks for your persistence.

PS: You would have to be old enough to remember the Mickey Mouse Club on TV to recognize “Anything Can Happen Day” :slight_smile: Each of the 5 weekdays had special theme. For some odd reason, I remember Thursday. Funny.

Hi Ron,

I’ll wait on the screen shots then :slight_smile:

What resolution is your monitor running at?
This is the only other thing I can think of that would influence things.

I don’t think screen resolution could be a factor.

The actual screen dot pitch is around 81dpi. (BIG pixels by today’s standards.)

Video card is set to its default 96dpi; therefore, everything on my monitor appears about 119% percent of “normal”. This is a very normal older display. No zooming or other weirdness anywhere. Perfect for my vision.

Cheers.

Pullo,

Two images of screenshots.

The first demonstrates the “jump”, the second demonstrates the “reload page” behavior.
You can tell from the URL that we are looking at your server.


Hope this helps.

Hi Ron,

Thanks for the screenshots.

I think I have fixed the FF bug now.
Could you please try out my updated demo and let me know if that works for you.

Pullo,

It’s apparent that you do not see what I see :).

Which begs the question, why is that so? REALLY! I would love to understand that one!

Back on track… version 2 of your code… unfortunately, the menu overflows the “transition point” (never changes to p:a) in all browsers and behaves erratically in Firefox. I have no idea why. Doesn’t make sense.

I went back and dorked with version 1 and have it working as desired in all browsers except Opera which always sets the menu to p:fixed when the page is reloaded; ie, the “look” can “break” if the page is reloaded while positioned below the transition point but instantly corrects itself when scrolled. It would seem that Opera requires the code that is triggered by $(window).scroll(function() to be triggered by a page reload, too, if that’s possible.

However, I’m happy enough with the way it is now. After all, what are the chances that an Opera user will reload the page while scrolled to the bottom?

But the nagging mystery is: Why are you unable to see what I see? Different platform, maybe? Are you running VMs on a Mac? I have been a FF user for quite a while, but it has been getting buggier and, as I said in an earlier post, I don’t trust it any more. It feels boggy.

FYI:


<script type="text/javascript">
$(document).ready(function() {
    var $nav = $('.nav'),
        $frame = $('.frame'),
        $page = $(document),
        nav_height = $nav.height(),
        frameHeight = $frame.height(),
        frameTopOffset = 4;

    $(window).scroll(function() {
        var newNavTop = 0,
            frameOutOfView = $page.scrollTop() - frameTopOffset,
            frameRemaining = frameHeight - frameOutOfView;
        if (frameRemaining <= nav_height) {
            $nav.addClass("absolute");
        } else {
            $nav.removeClass("absolute");
        }
    });
});
</script>

And I changed the height of the poster image back to 700px to make it easier to scroll the page.

If anyone else would care to join this party and test the code on their PC, I would be grateful.

Hi Ron,

Oh no!
That really doesn’t make sense, as it works fine for me in all browsers.

Sure:

$(document).ready(function(){
  $(window).trigger("scroll");
});

However, I’m happy enough with the way it is now. After all, what are the chances that an Opera user will reload the page while scrolled to the bottom?

I don’t know why we are seeing different things.
Let me explain what I did yesterday. Maybe that’ll help.

To reproduce:
I opened up my old demo in Firefox 21 on Windows 8. I resized the window, so that the viewport was smaller than the menu, then I reloaded the page.
At this point everything was still looking good.
I then scrolled to the bottom of the page, where as expected the menu moved up with the bottom of the container.
I then resized the window and the layout broke.

Just to avoid the possibility that my browser or your browser was caching something I have renamed my demos.

Here’s the old one (which breaks in FireFox if you follow the above mentioned steps).
Here’s the new one (which, for me at least, works in Firefox).

Just so that we are 100% sure, can you reproduce the bug in my old demo, then try the same thing with the new demo and let me know how you get on.

Yup, that would be really helpful.