passatgt
passatgt

Reputation: 4442

Need a clever solution for CSS Z-Index overlays

I have two position:fixed elements on my site and i want to make sure that only one of these elements are visible based on the z-index value. Hard to explain, but an image might help you to understand the issue:

Question explained on image

Also created a demo: http://jsfiddle.net/RM9Cx/1/

div {
    height:100%;
    background:#000;
    position:relative;
    z-index:10;
}

div.gray {
    background:#c8c8c8;
    z-index:12;
}

nav {
    left:45px;
    position:fixed;
    width:150px;
    height:150px;
    background:red;
    top:50%;
    margin:-75px 0;
    z-index:11;
}

nav.white {
    background:#00fff0;
    left:90px;
    z-index:13;
}

When you scroll down, you can notice that the red div is working fine, when it reaches a gray section, becomes hidden. I need to to the same thing with the "aqua" coloured div, just exactly the opposite. When its reaches the black section, it should be hidden, when reaches the gray section, it should be visible.

I hope any of this make sense...

Upvotes: 1

Views: 198

Answers (1)

Nico O
Nico O

Reputation: 14142

This is still work in progress, but it think enough to let the comunity work with it. http://jsfiddle.net/NicoO/RM9Cx/17/

The idea is to manipulate the DOM order of the "navigation" items. I try to identify the current pane (<div>) which is on top and the following one as well. Then the <nav> objects will be put inside of pane 1 and 2. The Top-Offset of the navigation is set via JS, since the panes will use overflow:hidden; to erase the desired areas.

This works, but only for the first two panes. The Problem that is left is caused because the <nav> items get placed in the following panes before the user have reached the end of the current pane. So we lose the <nav> objects. Maybe someone is willing to use this to work with.

Sorry, the code became a bit messy with all the experiments...

var $elements = $("div");
var offsets = new Array();
var userScrollTop = 0;
var $topPanel = 0;
var topPanelOffset;
var $followingPanel;
var $navPrimary = $("#primary");
var $navSecondary = $("#secondary");

// Get all top offsets of div elements
$elements.each(function(){
   var thisOffset = $(this).offset().top;
   offsets.push(thisOffset);
    // We need the attribute, so don't use .data()...
   $(this).attr("data-offset",thisOffset);
});

// Append event listener on scroll
$(document).scroll(function() {
    userScrollTop = $(document).scrollTop();

    if($topPanel && $followingPanel){
       $navPrimary.css("top", Math.max(0, (($(window).height() - $navPrimary.outerHeight()) / 2) +  userScrollTop) + "px");
       $navSecondary.css("top", Math.max(0, (($(window).height() - $navPrimary.outerHeight()) / 2)  + userScrollTop) - $topPanel.outerHeight() + "px");
    }    

    // Currently most on top panel
    var closestValue = getClosestValues(offsets,userScrollTop);
    if($topPanel && $topPanel.is($('[data-offset="'+closestValue[0]+'"]')))
           return true;   

    $topPanel = $('[data-offset="'+closestValue[0]+'"]');

    if(!$topPanel.length)
        $topPanel = $("div:first-of-type");


    $followingPanel = $topPanel.next("div");
    topPanelOffset = $topPanel.offset();    

    $topPanel.append($navPrimary);
    $followingPanel.append($navSecondary); 

});

Upvotes: 1

Related Questions