43

I have a number of div elements with different z-index. And I want to find the highest z-index among these divs - how can I achieve it?

CSS:

#layer-1 { z-index: 1 }
#layer-2 { z-index: 2 }
#layer-3 { z-index: 3 }
#layer-4 { z-index: 4 }

HTML:

<div id="layer-1">layer-1</div>
<div id="layer-2">layer-2</div>
<div id="layer-3">layer-3</div>
<div id="layer-4">layer-4</div>

I don't think this line can find the highest z-index though.

var index_highest = parseInt($("div").css("zIndex"));
// returns 10000
TylerH
  • 20,799
  • 66
  • 75
  • 101
Run
  • 54,938
  • 169
  • 450
  • 748
  • On Firefox, testing with jsFiddle, I get 1. Maybe you have some other `div` elsewhere in your HTML that has a `z-index` of 10000. – BoltClock Apr 15 '11 at 18:22
  • thanks BoltClock. can't find where I have the div with 10000 - strange! – Run Apr 15 '11 at 18:30
  • 2
    To everyone looking for a solution: beware of stacking contexts if you use a CSS opacity different than 1 : http://philipwalton.com/articles/what-no-one-told-you-about-z-index/ – pyb Oct 23 '15 at 14:43

11 Answers11

35

Note that z-index only affects positioned elements. Therefore, any element with position: static will not have a z-index, even if you assign it a value. This is especially true in browsers like Google Chrome.

var index_highest = 0;   
// more effective to have a class for the div you want to search and 
// pass that to your selector
$("#layer-1,#layer-2,#layer-3,#layer-4").each(function() {
    // always use a radix when using parseInt
    var index_current = parseInt($(this).css("zIndex"), 10);
    if(index_current > index_highest) {
        index_highest = index_current;
    }
});

JSFiddle demo

A general jQuery selector like that when used with an option that returns one value will merely return the first So your result is simply the z-index of the first div that jQuery grabs. To grab only the divs you want, use a class on them. If you want all divs, stick with div.

TylerH
  • 20,799
  • 66
  • 75
  • 101
justkt
  • 14,610
  • 8
  • 42
  • 62
  • 4
    there's one more thing you need to update `if(index_current>=index_highest)` (note the operator >=) because a html file is rendered top to bottom and having the same z-index will cause the later element to be rendered on top of the previous one. I'm not sure about how jQuery discovers the elements, but it stands to reason that it would parse the dom tree in the same manner (top to bottom) – Silviu-Marian Apr 14 '12 at 16:44
  • 6
    I think in the code it should be `.css("z-index")` instead of `.css("zIndex")`. – Matt Jul 04 '13 at 09:07
  • Thanks. I made an "improvement." I changed the selector to include all elements on the page. Pretty obvious but perhaps helpful to someone. change: $("#layer-1,#layer-2,#layer-3,#layer-4").each(function() { to: $("*").each(function() { – Mike Grimm Sep 04 '15 at 14:08
13

Here is a very concise method:

var getMaxZ = function(selector){
    return Math.max.apply(null, $(selector).map(function(){
        var z;
        return isNaN(z = parseInt($(this).css("z-index"), 10)) ? 0 : z;
    }));
};

Usage:

getMaxZ($("#layer-1,#layer-2,#layer-3,#layer-4"));

Or, as a jQuery extension:

jQuery.fn.extend({
    getMaxZ : function(){
        return Math.max.apply(null, jQuery(this).map(function(){
            var z;
            return isNaN(z = parseInt(jQuery(this).css("z-index"), 10)) ? 0 : z;
        }));
    }
});

Usage:

$("#layer-1,#layer-2,#layer-3,#layer-4").getMaxZ();
Aaron J Spetner
  • 2,117
  • 1
  • 18
  • 30
12

Besides @justkt's native solution above, there is a nice plugin to do what you want. Take a look at TopZIndex.

$.topZIndex("div");
TylerH
  • 20,799
  • 66
  • 75
  • 101
Anthony Accioly
  • 21,918
  • 9
  • 70
  • 118
  • 1
    Thanks heaps! The jQuery plugin archive is offline because they're rebuilding it. Here's the GoogleCode link: https://code.google.com/p/topzindex/downloads/detail?name=jquery.topzindex.1.2.zip – Max Leske Jun 28 '12 at 08:41
6

Try this :

var index_highest = 0;
$('div').each(function(){
    var index_current = parseInt($(this).css("z-index"), 10);
    if(index_current > index_highest) {
        index_highest = index_current;
    }
}); 
Jainendra
  • 24,713
  • 30
  • 122
  • 169
David
  • 1,101
  • 5
  • 19
  • 38
3

This is taken directly from jquery-ui, it works really well:

(function ($) {
  $.fn.zIndex = function (zIndex) {
      if (zIndex !== undefined) {
        return this.css("zIndex", zIndex);
      }

      if (this.length) {
        var elem = $(this[ 0 ]), position, value;
        while (elem.length && elem[ 0 ] !== document) {
          // Ignore z-index if position is set to a value where z-index is ignored by the browser
          // This makes behavior of this function consistent across browsers
          // WebKit always returns auto if the element is positioned
          position = elem.css("position");
          if (position === "absolute" || position === "relative" || position === "fixed") {
            // IE returns 0 when zIndex is not specified
            // other browsers return a string
            // we ignore the case of nested elements with an explicit value of 0
            // <div style="z-index: -10;"><div style="z-index: 0;"></div></div>
            value = parseInt(elem.css("zIndex"), 10);
            if (!isNaN(value) && value !== 0) {
              return value;
            }
          }
          elem = elem.parent();
        }
      }

      return 0;
    }
})(jQuery);
Andrew Barrett
  • 19,721
  • 4
  • 47
  • 52
3

This would do it:

$(document).ready(function() {
    var array = [];
    $("div").each(function() {
        array.push($(this).css("z-index"));
    });
    var index_highest = Math.max.apply(Math, array);
    alert(index_highest);
});

Try this

Hari Pachuveetil
  • 10,294
  • 3
  • 45
  • 68
2

I don't know how efficient this is, but you can use $.map to get all the z-indices:

var $divs = $('div'),
    mapper = function (elem) {
        return parseFloat($(elem).css('zIndex'));
    },
    indices = $.map($divs, mapper);

The indices variable is now an array of all the z-indices for all the divs. All you'd have to do now is apply them to Math.max:

var highest = Math.max.apply(whatevs, indices);
sdleihssirhc
  • 42,000
  • 6
  • 53
  • 67
1

Here how I got both lowest/highest z-indexes. If you only want to get the highest z-index and nothing more, then this function may not efficient, but if you want to get all z-indexes and the ids associated with it (i.e. for use with bring 'layer' to front/send to back, bring forward, send backward, etc), this is one way to do it. The function returns an array of objects containing ids and their z-indexes.

function getZindex (id) {

     var _l = [];
     $(id).each(function (e) {
         // skip if z-index isn't set 
         if ( $(this).css('z-index') == 'auto' ) {
              return true
         }
         _l.push({ id: $(this), zindex: $(this).css('z-index') });
     });
     _l.sort(function(a, b) { return a.zindex - b.zindex });
     return _l;
}

// You'll need to add a class 'layer' to each of your layer
var _zindexes = getZindex('.layer');
var _length = _zindexes.length;

// Highest z-index is simply the last element in the array
var _highest = _zindexes[_length - 1].zindex

// Lowest z-index is simply the first element in the array
var _lowest = _zindex[0].zindex;

alert(_highest);
alert(_lowest);
0

Vanilla JS, not 100% cross-browser. Including as reference for future readers/alternative method.

function getHighIndex (selector) {
    // No granularity by default; look at everything
    if (!selector) { selector = '*' };

    var elements = document.querySelectorAll(selector) ||
                   oXmlDom.documentElement.selectNodes(selector),
        i = 0,
        e, s,
        max = elements.length,
        found = [];

    for (; i < max; i += 1) {
        e = window.getComputedStyle(elements[i], null).zIndex || elements[i].currentStyle.zIndex;
        s = window.getComputedStyle(elements[i], null).position || elements[i].currentStyle.position;

        // Statically positioned elements are not affected by zIndex
        if (e && s !== "static") {
          found.push(parseInt(e, 10));
        }
    }

    return found.length ? Math.max.apply(null, found) : 0;
}
Kai
  • 9,038
  • 5
  • 28
  • 28
-1

Try my fiddle:

http://planitize.tumblr.com/post/23541747264/get-highest-z-index-with-descendants-included

This combines three advantages I haven't seen combined elsewhere:

  • Gets either the highest explicitly defined z-index (default) or the highest computed one.
  • Will look at all descendants of your selector, or all descendants of the document if none is supplied.
  • Will return either the value of the highest z, or the element that has the highest z.

One disadvantage: no cross-browser guarantees.

Wytze
  • 7,844
  • 8
  • 49
  • 62
-1

If you are doing what I think you're doing, there is no need. Just do this:

$('div[id^=layer-]').css('z-index', 0);
$(this).css('z-index', 1000);
jsSn0wMan
  • 3
  • 1
  • Please read the question carefully. He's has x amount of elements and want to get the one with the highest `z-index`. You're setting all the elements `z-index` to 0 and `$(this)` on your answer has reference to the `window` object not the elements – Ahmad Alfy Oct 03 '12 at 09:01