Why is my stack order reversed for my <img> elements?

134 Views Asked by At

I'm creating a website that changes backgrounds. I'm doing this by setting my background images to the same width/height as my browser and setting their opacity to 0.

When I want a specific background image to appear, I use Javascript to set the background image's opacity back to 1. All the background images are stacked on top of each other with a container that has absolute positioning. When I did this, I noticed something peculiar. It seems that the background <img> that comes FIRST in the code is on top of the background <img>s later in the code.

From my understanding, if two elements have the same z-index and overlap, the element that is LATER in the code will on top of the other. So shouldn't the <img> element that comes LAST in the code be on top of the element that comes first? Relevant code is below.

HTML:

<body>
<div id="bg_container">
<img id="bg_3"  src="bg/bg_midori.png" width="1366px" height="662px">
<img id="bg1_2" src="bg/bg1_2.png" width="1366px" height="662px">

<!-- When I test my website, "bg_3" is on top of bg1_2. Should bg1_2 be on top of bg_3? Both <img> are supposed to have the "cover_bg" class but I removed so it's obvious that "bg_3" is on top of bg1_2 !-->

</div>

CSS:

 body{
    background-image:url('bg/bg_image.jpg');
    /*Above is the default background image */

    }

#bg_container{
    width:1366px;
    height:662px;
    position:absolute;
    top:0px;
    left:0px;
    z-index:-1;
    overflow:hidden;
    }

.cover_bg{
opacity:0;
}

Any idea of what why my stack order for my background <img>s is reversed?

I noticed that when I used the code below, the background <img> that is later in the code is on top of <img> proceeding it, just as I expected.

<!DOCTYPE html> 
<html> 
<head> 
<style> 
img{
    position:absolute;
    left:0;
    top:0;
    }
</style>
</head> 
<body> 

<div id="bg_container">
<img id="bg_3" class="cover_bg" src="bg/bg_midori.png" width="1366px" height="662px">
<img id="bg1_2" class="cover_bg" src="bg/bg1_2.png" width="1366px" height="662px">

<!-- In this case bg1_2 is on top of bg_3, as expected !-->
</div>
</body>
</html>
2

There are 2 best solutions below

0
On

Just a little link that can help you.

From this post : what-no-one-told-you-about-z-index

Positioned elements with negative z-indexes are ordered first within a stacking context, which means they appear behind all other elements. Because of this, it becomes possible for an element to appear behind its own parent, which is normally not possible. This will only work if the element’s parent is in the same stacking context and is not the root element of that stacking context.

Depending on how you apply background changes. One way could be to apply non-negative value for z-index or use background_url css property for #bg_container that can modify via jQuery.

1
On

https://www.w3.org/TR/css3-background/#layering

The stacking order isn't messed up at all, it's just counterintuitive.

HTML elements and CSS backgrounds have their own stacking rules, which work in opposition to one another. HTML elements e.g. <img> render from the bottom up (the most recent element will appear above elements rendered first in the stack). CSS backgrounds render from the top down (the most recent background layer will appear below layers rendered first in the stack).