5
\$\begingroup\$

I have to display a cache layer on the whole viewport (to then display a kind of dialog box).
Without surprise I create a <div> element with {position: fixed; top: 0 left: 0; width: 100%; height: 100%: background-color: #...; opacity: ...}.

But I faced the issue that I may encounter pages where some elements have a z-index other than 0 or auto.
So I must add a z-index property which surpasses the maximum one currently featuring in the page.

I'm currently using the following snippet:

var zMax = 0;
$('body *').each(function() {
  var zIndex = +$(this).css('zIndex'); // ("+" casts to number or NaN)
  if (zIndex > zMax) {
    zMax = zIndex;
  }
});

It works fine, but I'm not really happy with it: merely based on brute-force, it appears as "too easy" and a bit overkill.
I googled for other solutions and found a lot (notably on SO), but no one seems simpler than mine.

TL;DR; Is there some smarter alternative?


EDIT: to be more clear, here is an example of how the "cache layer" works:

$(document).ready(function() {
  $('#go, #goz').click(showDialog);
  
});
function showDialog() {
  $('body').append('<div id="cache" />');
  $('body').append('<div id="dialog"><p id="text" /><button id="cancel">Cancel</button></div>');
  $('#cancel').click(cancel);
  var text = 'Without z-index, cache doesn\'t cover image';
  if (this.id == 'goz') {
    $('#cache').css({zIndex: 101});
    $('#dialog').css({zIndex: 102});
    text = 'With z-index, cache covers all';
  }
  $('#text').html(text);
}
function cancel() {
  $('#dialog, #cache').remove();
}
#cache {
  position: fixed;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  background-color: #444;
  opacity: .7;
}
img {
  position: relative;
  z-index: 100;
}
#dialog {
  position: fixed;
  left: 100px;
  top: 50px;
  width: auto;
  border: 1px solid #000;
  background-color: #fff;
  padding: 1em;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<p>Longe glabro ortus tempus crimina perquam notarius Magnentio odorandi in membra quos a perquam supergressus.</p>
<img src="https://i.stack.imgur.com/u65Rp.png?s=48&g=1">
<p>Batnae municipium in Anthemusia conditum Macedonum manu priscorum ab Euphrate flumine brevi spatio disparatur.</p>
<button id="go">Go (simple)</button>
<button id="goz">Go (with z-index)</button>

Using the "Go (simple)" button, you see that the image is not covered by the cache (in this case, because it both has position: relative and a given z-index).
Using the "Go (with z-index)" button, we have set z-index of the cache and dialog layers to a sufficient value to overstrip any other element's ones (here it's hard coded).

The important point is that my tool snippet may be included everywhere, notably in the context of an existing app (like a CMS).
Since I obviously have no control over such an app, I must discover which is the current max z-index: then the cache and dialog layers will get this max value +1 (respectively +2).

\$\endgroup\$
  • \$\begingroup\$ Not sure what you mean by "cache layer" here. Can you add some HTML markup that this javascript works with for more context? What then happens once zMax is calculated? \$\endgroup\$ – Mike Brant Oct 5 '16 at 17:07
  • \$\begingroup\$ Do you really have that many elements in your CSS definitions that can even have a z-index value? Is your CSS structured such that you have certain classes, for example, that use z-index that you could use as a more narrow selector? Iterating over every element in within the document body seems like a bad approach. \$\endgroup\$ – Mike Brant Oct 5 '16 at 17:10
  • \$\begingroup\$ @MikeBrant Sorry, I was too brief. Please look at my edit. \$\endgroup\$ – cFreed Oct 5 '16 at 18:51
2
\$\begingroup\$

While I understand you're looking for a snippet that works well on an underlying page you have no control over, any solution for such a problem would technically be a hack.

Your best bet, though certainly not a fool-proof solution, is to just use a very large or perhaps the maximum possible z-index (supposedly 2147483647, though certainly not standardised - I'd just go with something like 10000000) on your element.

\$\endgroup\$
  • \$\begingroup\$ Thanks for your suggestion. But it can't be used in my case, because the pair cache+dialog may be "stacked". I.e., like working on a main page may be temporarily interrupted by a dialog, the work in this dialog may be temporarily interrupted by a second level dialog... and so on. It's why I must always be able to evaluate which is the current max z-index, including those of my previous level(s) dialogs! In the other hand I'm a bit surprised you name "hack" the process of looking for the max z-index: it only gets an information and doesn't change anything of the original page. \$\endgroup\$ – cFreed Oct 5 '16 at 19:36
  • \$\begingroup\$ If you ensure that the "second level dialog" is inserted after the first level (which you already do, since append inserts elements to the end of the parent) and they have the same z-index, the second level will be on top of first. \$\endgroup\$ – fstanis Oct 5 '16 at 19:42
  • \$\begingroup\$ Yes, but... Note that, since cache and dialog have both position: fixed, as soon as cache have x as z-index dialog must have x+1. So if the z-index are the same from level to level, the 1st level dialog keeps overstripping the 2nd level cache. And here is the point: each dialog may have quite different contents (so quite different sizes) and then at 2nd level we may have visible parts of the 1st level dialog! \$\endgroup\$ – cFreed Oct 5 '16 at 19:51
  • 1
    \$\begingroup\$ You needn't do that - just make sure both the dialog box and the "cache" layer have the same z-index and it will work fine (again, order in HTML applies, since they are both position: fixed). Here's a fiddle. \$\endgroup\$ – fstanis Oct 5 '16 at 20:49
  • \$\begingroup\$ I first thought you were wrong (this was based on issues I previously got by example with elements like the image on my sample snippet above; but it was only due to its position). So I did some tries to check, and I agree with your solution, which also simplifies handling my own components z-index (I increased it successively for each of them, while I can use only one, like your sample shows). Thanks for your time. \$\endgroup\$ – cFreed Oct 5 '16 at 23:17

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.