Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

reversing z-index based from page render order

Example Markup:

<div class="wrapper">
    <h2>Trigger</h2>
    <div>This is some content</div>
</div>
<div class="wrapper">
    <h2>Trigger</h2>
    <div>This is some content</div>
</div>
<div class="wrapper">
    <h2>Trigger</h2>
    <div>This is some content</div>
</div> 

Example CSS:

.wrapper {z-index: 1}
.wrapper div {display: none; position: absolute;}

Via javascript (jQuery) I'm attaching a click event to each h2 that will then switch the content div to display: block.

The intent is that these are expandable blocks of content that will overlap anything else on the page.

The catch is that I'd like the first one to overlap the second, which would overlap the 3rd in the event that all of them are open.

However, since each one is being rendered AFTER the previous one, the actual stacking order is reversed (The last content div created end sup overlaying the previously created once).

Is there a clever way of reversing this behavior with CSS/HTML? Or is the solution to let the page render, then via javascript, grab all of the content divs in order and give them each a z-index in reverse order?

UPDATE:

Here's some more specific markup:

<div style="padding: 10px;">Hello World
    <div style="position: relative; top: -5px;">
        <div style="position: absolute; background: yellow;"><p>This</p><p>is</p><p>overlapping</p></div>
    </div>
</div>
<div style="padding: 10px;">Hello World
    <div style="position: relative; top: -5px;">
        <div style="position: absolute; background: orange;"><p>This</p><p>is</p><p>overlapping</p></div>
    </div>
</div>
<div style="padding: 10px;">Hello World
    <div style="position: relative; top: -5px;">
        <div style="position: absolute; background: red;"><p>This</p><p>is</p><p>overlapping</p></div>
    </div>
</div>

The following markup will produce 3 divs, each with a colored div overlapping. Due to the render order, the last absolutely positioned DIV (red) will be on top of the one before it (orange).

I can't figure out what type of z-indexes I need to apply to get the FIRST colored overlapping div to be on top. The order from top-to-bottom in terms of z-index should mirror the markup (yellow on top, red on bottom).

This is, of course, reverse of the standard.

I'm willing to use javascript to fix this post-display but I'm still struggling for the exact CSS that I need to apply via javascript. Is what I'm after doable?

like image 998
DA. Avatar asked Feb 26 '10 21:02

DA.


People also ask

How do you use Z index without absolute positioning?

Yes: use position:relative; z-index:10 . z-index has no effect for position:static (the default).

How do I change stacking order in CSS?

We can change the stacking order by adding the position property. Any positioned elements (and their children) are displayed in front of any non-positioned elements. Positioned elements have a position value relative, absolute, sticky or fixed. Non-positioned elements are the ones with default position (static).

How do I change stacking context?

You don't need to apply z-index and position to create a new stacking context. You can create a new stacking context by adding a value for properties which create a new composite layer such as opacity , will-change and transform . You can see a full list of properties here.

How do I fix a Z index problem?

To sum up, most issues with z-index can be solved by following these two guidelines: Check that the elements have their position set and z-index numbers in the correct order. Make sure that you don't have parent elements limiting the z-index level of their children.


2 Answers

So still no answer here, i just did something similar, even though my workaround is 100% hack, if anyone else comes to this page, it did work!

#nav ul li:nth-child(1) {
        z-index:10; 
    }
    #nav ul li:nth-child(2) {   
        z-index:9;  
    }
    #nav ul li:nth-child(3) {
        z-index:8;  
    }
    #nav ul li:nth-child(4) {   
        z-index:7;  
    }
    #nav ul li:nth-child(5) {
        z-index:6;  
    }
    #nav ul li:nth-child(6) {   
        z-index:5;  
    }

I just had that and as long as i didn't get over 10 elements it seems to work...

like image 185
jamie-wilson Avatar answered Jan 13 '23 11:01

jamie-wilson


Here is SASS function for the top answer:

@for $i from 1 through 10 {
   &:nth-child(#{$i}) {
     z-index: #{10 - $i};
   }
}
like image 21
Matthew Leonard Avatar answered Jan 13 '23 10:01

Matthew Leonard