1
<div class="content-wrapper">
    <div class="popup">
        <div class="close">
        </div>
    </div>
</div>

.content-wrapper is relatively positioned and contains all the page content (not just the popup).

.popup is absolutely positioned.

.close is also absolutely positioned.

I have some javascript to move close when the cursor enters popup (so I have a nice close bar appear out the side). The best way I have found to do this is just to move using jQuery animate. Hiding/showing creates a stuttering affect even .stop() wasn't able to solve. My problem is in trying to hide .close behind .popup. No matter what z-index I set for the two divs .close will not sit behind .popup.

Is it possible to have an absolutely positioned div inside another absolutely positioned div sit behind its parent, and if so how?

Temani Afif
  • 245,468
  • 26
  • 309
  • 415
Styphon
  • 10,304
  • 9
  • 52
  • 86
  • changing markup is an option? – Fabrizio Calderan Apr 05 '12 at 14:21
  • Possibly, the popup moves around the screen (hence why it's absolutely positioned), so having the close inside the popup was the only solution I could think of. If better markup will work then I'm willing to try. – Styphon Apr 05 '12 at 14:26

3 Answers3

6

Yep, use z-index: http://jsfiddle.net/tGd4Q/

HTML:

<div class="content-wrapper">
    <div class="popup">
        <div class="close">
        </div>
    </div>
</div>​

CSS:

.popup, .close { position: absolute; height: 200px; width: 200px; }
.popup { background: #f00; }
.close { background: #ff0; top: 25px; left: 25px; z-index: -1; }​

This won't work with IE7 standards though. I suggest using jQuery(or other framework of your choosing) to hide the div:

$('.popup .close').hide();
Nick McCormack
  • 530
  • 2
  • 9
  • I see it works in jsfiddle, but that doesn't work in my code. – Styphon Apr 05 '12 at 14:33
  • 1
    It works, but only if you have .close set to -1 and .popup not set at all. Any other combination and it doesn't, weird. Works for my purposes though, thank you. – Styphon Apr 05 '12 at 15:16
2

Stacking indices are most of the time relative to siblings, so you cannot put a child behind it's parent using z-index.

Here is some more information about that.

This is the stacking order:

  1. The borders and background of the current stacking context
  2. Positioned descendants with negative z-index
  3. Nonpositioned block-level descendants with no z-index property defined -- paragraphs, tables, lists, and so on
  4. Floating descendants and their contents
  5. Nonpositioned inline content
  6. Positioned descendants with no z-index, z-index: auto, or z-index: 0
  7. Positioned descendants with z-index greater than 0

Nick McCormack uses z-index: -1 in his answer. This is indeed one exception to what your feelings give in. Beware that z-index: -1 moves an element behind many of your elements to the background.

Browser differences

Beside that, Internet Explorer does not support negative stacking indices and is very strict with element (child/parent) positions. Every element level has it's own stacking context, so have to 'communicate' via the parent element. See this explanation.

According to Smashing Magazine, the select element, which is a windowed control, has naturally a higher stacking index.

According to the Shadowbox troubleElement option, I presume that object, embed and canvas have the same issues.


If you want to hide .close, why don't you really hide it instead of moving it behind .popup?

$('.close').hide();
Frank van Wijk
  • 3,234
  • 20
  • 41
  • How does -1 function on different browsers? Do you know? – Clarence Klopfstein Apr 05 '12 at 14:31
  • When I tried to use .show and .hide the css positioning of the object got screwed up. It would stutter like mad then move to left 0 all the time. – Styphon Apr 05 '12 at 14:32
  • -1 works in everything but IE7, but isn't a good solution to this dilemma. The 'right' solution isn't a CSS one unfortunately, but alas, it is what the question asks. – Nick McCormack Apr 05 '12 at 14:35
  • 1
    @Styphon: show and hide of what object? If your `.close` is positioned absolute, this should not influence the position of the other elements in the `.popup`. Be sure that you always give up a horizontal and vertical position to absolute positioned elements, otherwise IE is confused. – Frank van Wijk Apr 05 '12 at 14:40
  • @Clarence Klopfstein: I updated my answer with some information about other browsers. – Frank van Wijk Apr 05 '12 at 14:51
0

No, you will not be able to put it behind its parent. However you could change its display mode to none, so it isn't seen at all. Then when you need to see the div, change it to show.

Simple jQuery:

$('.close').hide();
$('.close').show();

There are other ways as well, such as adding an attribute of style with display:none or display: inline-block as a setting.

Update: According to comments in other answers, there IS a way to do it with z-index. Still thinking the hide/show is the way to go though. Very clear what you are doing on your UI.

Clarence Klopfstein
  • 4,682
  • 10
  • 33
  • 47