开发者

reversing z-index based from page render order

开发者 https://www.devze.com 2022-12-21 21:29 出处:网络
Example Markup: <div class=\"wrapper\"> <h2>Trigger</h2> <div>This is some content</div>

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?


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...


Here is SASS function for the top answer:

@for $i from 1 through 10 {
   &:nth-child(#{$i}) {
     z-index: #{10 - $i};
   }
}


Shiny new CSS flexbox technology makes this a bit easier, but the downside is the actual content will be reversed. This doesn't have to be a big problem, it's just semantically weird.

In short: wrap everything in a container with these styles:

display: flex;
flex-direction: column-reverse;

See the fiddles for a working example (hover over the wrapper elements to see the action).

It's useful if you don't want to rely on javascript to dynamically check z-indexes every time you update the content. If the <div class="wrapper"> elements are inserted on the fly (or any other reason specific styles cannot be set in advance) The CSS rules in the example should be enough to take care of the z-indexes IF you insert the <div>s in reverse order.

This is your current setup: http://jsfiddle.net/dJc8N/2/

And this is the same HTML, with added CSS (notice the numbers in the <h2> tags): http://jsfiddle.net/Mjp7S/1/

EDIT:

The CSS I posted is probably not ready to be copy-pasted yet. This, however, is:

display: -webkit-flex;
display: -moz-flex;
display: -ms-flex;
display: -o-flex;
display: flex;
-webkit-flex-direction: column-reverse;
-moz-flex-direction: column-reverse;
-ms-flex-direction: column-reverse;
-o-flex-direction: column-reverse;
flex-direction: column-reverse;


I had exactly this problem, but an indeterminate number of elements, and possibly too many to make the CSS hack posted by jamie-wilson feasible. Also, since my page is generated dynamically with PHP, I didn't want to fuss with reversing the order of everything in the DOM and using flexbox the way Sandy Gifford suggested. I found an extremely simple and elegant jQuery solution to use instead:

$(document).ready(function() {

  var item_count = $('your-selector').length;

  for( i = 0; i < item_count; i++ )
  {
    $('your selector').eq( i ).css( 'z-index', item_count - i );
  }

});

I can't speak to how performant this is, but with ~35 items I didn't notice any delays.

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号