Search code examples
htmlcssz-index

CSS z-index mystery


I have some problems with CSS and z-index. Let me show you an example

example

Suppose that on a first moment it only appears the tag pointers. Then, when I click one of this pointers appears a tag globe. I want that the tag pointers appears always under the tag globes, and I want too that every time I open a tag globe it appears over all other tag globes opened.

My div structure is:

<div id="t01" class="tag">
    <div class="small">
        <div class="globe">
            <div class="in-globe">
                <!--tag globe content-->
            </div>
        </div>
        <div class="globe-arrow"></div>
    </div>
</div>

And the related CSS code is this:

.tag {
    z-index: 3;
    position: absolute;
    left: 0; /*JavaScript modified*/
    top: 0;  /*JavaScript modified*/
    width: 19px;
    height: 26px;
    padding: 0 11px 10px 15px;
    background: url('../../images/zoom/tag.png') no-repeat center;
}
.small {
    cursor: pointer;
    width: 19px;
    height: 26px;
}
.globe-arrow {
    position: absolute;
    left: 23px;
    bottom: 30px;
    width: 8px;
    height: 6px;
    background: url(../../images/zoom/tag_arrow_UR.gif) no-repeat;
    z-index: 5;
}
.globe {
    position: absolute;
    left: 23px;
    bottom: 30px;
    z-index: 4;
}
.in-globe {
    font-size: 11px;
    margin: 0 0 3px 3px;
    padding: 3px;
    background: #FFF;
    border: 1px solid #000;
}

The 'tag' is all the conglomerate, and its background is the tag pointer image. However, this image has some shadows and I only want that a certain zone can be clicked. Then, the 'small' div has this function. The 'globe' and 'in-globe' divs are where the content of the globe is written (it could be an only div, there are two for historical reasons), and the 'globe-arrow' div is basically a little image to show this small arrow over the globe.

With this structure it doesn't work. In a same conglomerate, a globe is always over a tag, but an entire conglomerate defined before in the html code appears entirely under a newer one. In the same way, although a globe is inserted by JavaScript always after an older one (logically) the tag conglomerate is inserted when the page is loaded and then the overlapping works like I said.

Can you propose an smart way to reach my objective? Think that I'm interested on positioning the globe respective to the tag, because when I drag a pointer with a globe opened I want that the globe moves with it by CSS, not by JavaScript.


Solution

  • I solved the problem. There's no magic way to do it. I had to change the way I structure tags. It seems that z-index inherits from the container div, then like the parent has less z-index, a son of another parent with the same z-index appears under the first although this son has a bigger z-index. It's very confusing, yes.

    In few words, I define a tag-container (to positionate the tag), into it I define a pointer and a tag globe. The first with less z-index than the second. Now, as all the divs with z-index has the same level all tag globes appear over all tag pointers.

    I want that every time I open a new tag globe it appears over the opened globes. Against my desires, I had to use JavaScript for this because with a same z-index the browser show over the last defined div. This is ugly. I build a stack of z-index's that increases with more globes and decreases when I close them. Then I simply edit the css dinamicaly to put this new z-index to the new globe.

    Thank you for your attention and help :) I hope this could be useful for somebody.