For my first post I’m going to write about the navigation bar on my own site.

I’d decided on fixed navigation - as the user scrolls, the navigation is fixed relative to the browser window, rather than in relative to the document.

Fixed navigation on the right hand side of the window was always going to come with some problems - for a start, Internet Explorer 6 doesn’t support fixed positioning (although there are JavaScript fixes), but I’ll come to IE6 later.

Having fixed navigation meant that the navigation bar would, without doubt overlap the content. In fact, I had deliberately designed the page so that the site’s right hand column aligned horizontally with the navigation menu.

When the page first loads, the navigation appears on top of the grey header. As you scroll down the page, the navigation then hovers over the white background. As it starts to overlap the content in the right-hand column, the sharp edges of the navigation on top of the content looked odd. Images behind the navigation glared through the 2 pixel gap between menu items, and the nav underline looked like it was crossing out any text it was obscuring.

So to achieve something better looking, I sacrificed a bit of accessibility for style, and also went to something you should only use in emergencies - the z-index.

Nav at page top

Nav while scrolling

The first thing to notice is that there is a “haze” underneath the navigation bar - a gradient that fades from white to transparent, giving the effect of the content fading out around the navigation. There is also a gradient to the left of the nav - so that there is a soft edge on pages where there is no right-hand column.

To prevent the content appearing through the gaps between menu items, I used a DIV element with a white background to sit behind the menu. Notice that you can’t see any of the page background dots to the right of the menu.

The markup:


<div id="navigation"> 
    <div id="navleft" class="behind"></div> 
    <ul>
        <li class="home"> 
            <a class="down" href="#top">Home</a> 
        </li> 
        <li class="latest"> 
            <a href="#latest">Latest</a> 
        </li> 
        <li class="portfolio"> 
            <a href="#portfolio">Portfolio</a> 
        </li>
        <li class="hireme"> 
            <a href="#hireme">Hire Me</a> 
        </li>
    </ul>
    <div id="navbottom" class="behind"></div> 
    <div id="navbackground" class="behind"></div> 
</div>

The CSS:


#navigation { position: fixed; }
#navigation ul { z-index: 12; border-bottom: 1px solid #4E4F4F; }
.behind { z-index: 8; }

The header has a z-index of 10, so sits above elements with the .behind class. The navigation list with a z-index of 12 is visible above the header.

Positioning the menu

Fixing the navigation menu directly above the right hand column caused difficulties. The main content area of the site is centered, so the distance between the edge of the screen and where the menu should appear would vary, depending on the size of the browser window.

Setting the Left, Right Top or Bottom properties in an absolutely positioned element positions it in relation to the first relatively positioned parent. Setting the left, right, top or bottom properties of a fixed-position element positions it relative to the browser window - which is no good when you want it to appear relative to something that is centered.

Although fixed position elements are removed from the “document flow”, they are positioned in relation to the first relatively positioned parent, only if left, right, top or bottom are not set. This allows you to set the margin-left property and the menu is positioned in relation to the relatively positioned parent. However, once the element has been positioned relative to that parent, it is then fixed in respect to the browser.

Margin-left on fixed position

In the above image, the nav has been positioned relatively to the centered content, with a margin-left set to position it above the right hand column. But what happens if the content is too big horizontally for the browser, for example if you are viewing with a screen resolution of 800x600?

Margin left and window resize

When the page loads, the navigation is positioned directly above the right hand column - perfect. But the width of the content is bigger than the viewable area, and so the navigation also is not totally visible. But as the user scrolls horizontally to see the additional content, the nav is fixed in relation to the window and so most of the menu options are not visible.

The solution

The navigation is set to have a right position of 0 - aligning it to the right of the window. If the user is viewing at 800 x 600 or if they resize the window, the navigation is always visible - it is fixed at the top right of the viewable area. But now the nav is not above the right column. That is fixed with a tiny bit of jQuery:


$(document).ready(function() {

    var columnright = $('.column-right:first');
    function onResize() {
        // if there is a right hand column, and all the content fits in the browser without scrolling horizontally
        if ((columnright.length > 0) && ($(window).width() > 990)) {

            // set the width of the navigation container so that it's positioned above the right column.
            var newWidth = $(window).width() - columnright.offset().left;
            nav.width(newWidth);
        }
    }
    $(window).resize(onResize);
    onResize();
});

This also causes the navbackground and navbottom divs to expand along with the rest of the navigation.

Internet Explorer 6

Internet Explorer does not support Fixed positioning, so people using the antiquated browser would have a slightly different experience. Absolutely positioning the navigation relative to the centered content elements the horizontal scrolling problems, but the navigation would not be fixed to the top of the screen as the user scrolls down. Instead, I simply created anchored links after each section of content back to the header.

And so…

So finally, we have a right-aligned, fixed positioned navigation menu that works in IE7 & 8, with or without JavaScript enabled, and an accessible solution for IE6 users.

« Back