6
\$\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.sstatic.net/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\$
3
  • \$\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
    Commented Oct 5, 2016 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
    Commented Oct 5, 2016 at 17:10
  • \$\begingroup\$ @MikeBrant Sorry, I was too brief. Please look at my edit. \$\endgroup\$
    – cFreed
    Commented Oct 5, 2016 at 18:51

1 Answer 1

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\$
5
  • \$\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
    Commented Oct 5, 2016 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
    Commented Oct 5, 2016 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
    Commented Oct 5, 2016 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
    Commented Oct 5, 2016 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
    Commented Oct 5, 2016 at 23:17

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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