about the only way i can think of to tell is to get the dom paths of the elements involved and check which one comes first by declaration; this should give you an idea in the absence of z-index which element would naturally be shown 'on top' of the other.
function getAncestors(ele) {
var ancestors = [ele];
while(ele.parentElement) { // walk all parents and get ancestor list
ele = ele.parentElement;
ancestors.push(ele);
}
return ancestors.reverse(); // flip list so it starts with root
}
function declaredBefore(ele1,ele2) {
var a1 = getAncestors(ele1);
var a2 = getAncestors(ele2);
for(var i=0;i<a1.length;i++) { // check path, starting from root
if(a1[i] !== a2[i]) { // at first divergent path
var testNodes = a1[i-1].childNodes; // get children of common ancestor
for(var j=0;j<testNodes.length;j++) { // check them for first disparate ancestor
if(testNodes[j] === a1[i]) { return true; } // ele1 is first
if(testNodes[j] === a2[i]) { return false; } // ele2 is first
}
}
}
return undefined; // could not determine who was first
}
function isAbove(ele1, ele2) {
// rudimentary z-index check for eles sharing a parent
if(ele1.parentNode === ele2.parentNode) {
var z1 = ele1.style.zIndex;
var z2 = ele2.style.zIndex;
if(z1 !== undefined && z2 !== undefined) { // if both have z-index, test that
return z1 > z2;
}
}
return declaredBefore(ele2, ele1); // if 2 is declared before 1, 1 is on top
}
this solution is far from bulletproof, but it should at least let you know which element is declared last, accounting for dom tree hierarchy. it also does not compare zIndex unless the elements share a parent, although you could probably modify that to check zIndex hierarchy of parents as well.