Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Reversing default z-index for children in an HTML element

So, the spec defines that elements are drawn "in tree order" for in-flow, non-positioned elements of similar block level or float status and identical z-index. This, of course, means those declared last in the HTML markup are drawn on top. But what if we want that order to be reversed for arbitrary children in a particular container?

For instance, say we have an indefinite number of overlapping float divs in a parent div:

__________________________________
|  _________________________      |
|  | samant| allis| rachael |...  |
|  |_______|______|_________|...  |
|_________________________________|

That we want instead to look like this:

__________________________________
|  _________________________      |
|  | samantha |lison |chael |...  |
|  |__________|______|______|...  |
|_________________________________|

jsfiddle

Is there still no way to achieve this with css alone? If not, what would be the most efficient and safe way to achieve this functionality with javascript for arbitrary child elements?

Questions have been asked previously for similiar functionality, but not specifically for use in a generic sense with an arbitrary number of child elements. See here and here.

like image 755
NanoWizard Avatar asked Jan 05 '15 21:01

NanoWizard


People also ask

Do child elements inherit Z index?

No, it isn't inherited.

What is the default Z index HTML?

The Default z-index Value of HTML Elements The default z-index value of all the elements on a web page is auto, which corresponds to 0 where no z-index is assigned. An element with z-index: -1 will be displayed behind all other elements on the page, assuming they are given no z-index values.


2 Answers

A simple javascript solution is to get all the elements using querySelectorAll, then forEach and set the z-index to the element count - current index:

var elems = document.querySelectorAll(".container2 .floater");
Array.prototype.forEach.call(elems, function(e, i) {
    e.style.zIndex = elems.length - i;
});
.container2 {
    border: 3px solid teal;
    padding: 2em;
    display:inline-block
}


.container2 .floater {
    border: 1px solid gray;
    background: #444;
    color: white;
    float: left;
    padding: 1em;
    margin: -1em;
    position: relative;
}
<div class="container2">
    <div class="floater">Item 1</div>
    <div class="floater">Item 2</div>
    <div class="floater">Item 3</div>
    <div class="floater">Item 4</div>
    <div class="floater">Item 5</div>
    <div class="floater">Item 6</div>
</div>
like image 165
Rhumborl Avatar answered Oct 19 '22 09:10

Rhumborl


You can reverse the order of the elements in the document tree to make them overlap like you want.

And then reverse their order using CSS, to place them in the right position again.

This can be achieved, for example, using

  • Flexible boxes:

    wrapper {
      display: flex;
      flex-direction: row-reverse; /* or `column-reverse` */
      justify-content: flex-end;
    }
    

    ul {
      display: flex;
      list-style: none;
      padding: 0 0 0 1em;
    }
    ul.reversed {
      flex-direction: row-reverse;
      justify-content: flex-end;
    }
    li {
      border: 1px solid;
      margin-left: -1em;
      background: #fff;
    }
    <ul>
      <li>Samantha</li>
      <li>Allison</li>
      <li>Rachael</li>
    </ul>
    <ul class="reversed">
      <li>Rachael</li>
      <li>Allison</li>
      <li>Samantha</li>
    </ul>
  • Floating elements:

    wrapper {
      float: left;
      clear: both;
    }
    item {
      float: right;
    }
    

    ul {
      list-style: none;
      float: left;
      clear: both;
      padding: 0 0 0 1em;
    }
    li {
      float: left;
      border: 1px solid;
      margin-left: -1em;
      background: #fff;
    }
    ul.reversed > li {
      float: right;
    }
    <ul>
      <li>Samantha</li>
      <li>Allison</li>
      <li>Rachael</li>
    </ul>
    <ul class="reversed">
      <li>Rachael</li>
      <li>Allison</li>
      <li>Samantha</li>
    </ul>
  • Direction:

    wrapper {
      direction: rtl;
      text-align: left;
    }
    item {
      direction: ltr;
    }
    

    ul {
      list-style: none;
      padding: 0 0 0 1em;
      text-align: left;
    }
    li {
      display: inline-block;
      border: 1px solid;
      margin-left: -1em;
      background: #fff;
    }
    ul.reversed {
      direction: rtl;
    }
    ul.reversed > li {
      direction: ltr;
    }
    <ul>
      <li>Samantha</li>
      <li>Allison</li>
      <li>Rachael</li>
    </ul>
    <ul class="reversed">
      <li>Rachael</li>
      <li>Allison</li>
      <li>Samantha</li>
    </ul>
like image 25
Oriol Avatar answered Oct 19 '22 10:10

Oriol