Gal Ziv
Gal Ziv

Reputation: 7372

z-index not working with position absolute

I opened the console (chrome\firefox) and ran the following lines:

$("body").append("<div id=\"popupFrame\" style=\"width:100%;height:100%;background-color:black;opacity:0.5;position:absolute;top:0;left:0;z-index:1;\" />");
$("body").append("<div id=\"popupContent\" style=\"width:200px;height:200px;z-index:1000;background-color:white;\" >dasdasdsadasdasdasdasdasd</div>");

The #popupContent should be above all but it's affected by the #popupFrame opacity.

The content is not contained in #popupFrame which makes this very weird.

The goal is to create a firefox-like alert box.

Upvotes: 194

Views: 372867

Answers (9)

Jaxon
Jaxon

Reputation: 81

You have to specify the exact position. i used top: 0 and right: 0

const para = document.createElement("div");
para.style.backgroundColor='black';

para.style.height='100%';

para.style.position='absolute'
para.id='newgrayscreen'
// Append to body:
function next(){
document.body.appendChild(para);
}
#newgrayscreen{
    top: 0;
    right: 0;
    z-index: 5000009000;
    position: relative;
    width: 100%;
    opacity: 50%;
    height: 100%;
}
<p>blah blah blah</p>
<input type='button' onclick="next();" value="click to make a gray screen appear on top of everything" >

Upvotes: 0

ianrandmckenzie
ianrandmckenzie

Reputation: 482

If you're a big 'ol dumdum like me (but know your positioning rules are 100% correct) trying to get something like this:

undesired result

to look like this:

enter image description here

Your solution may be as simple as ensuring your background is not transparent for the element you want in front of/behind the other element.

Upvotes: 3

Serhat MERCAN
Serhat MERCAN

Reputation: 1098

It may be too late, but it can be preferred as an alternative method. The order of layering for displaying elements in the absolute position depends on the order in which the elements are inserted into the parent element. In other words, instead of using z-index, it is possible to send it to the back by adding it with $(parent).prepend(me), and to bring it to the front by adding it with $(parent).append(me).

function BringToFront(){
  $("#parent").append($("#me"));
}

function SendToBack(){
  $("#parent").prepend($("#me"));
}
#mySister{
  position:absolute;
  left:25px;
  top:25px;
  width:100px;
  height:100px;
  background-color: red;
}

#me{
  position:absolute;
  left:50px;
  top:50px;
  width:100px;
  height:100px;
  background-color: yellow;
}

#myBrother{
  position:absolute;
  left:75px;
  top:75px;
  width:100px;
  height:100px;
  background-color: blue;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

<div id="parent">

  <div id="mySister">&nbsp;</div>

  <div id="me">Hello! this is me!</div>
  
  <div id="myBrother">&nbsp;</div>

</div>

<button type="button" onclick="BringToFront()">Bring to front</button>
<button type="button" onclick="SendToBack()">Send to back</button>

Upvotes: 1

Ayoub Benayache
Ayoub Benayache

Reputation: 1164

I had the the same problem, and i tried to solve it by appending the element with absolute position in a div with a sticky position, my problem was with speeddial (reactjs + material), so i dont know if it will work with all cases.

Upvotes: 1

Ericgit
Ericgit

Reputation: 7073

I faced this issue a lot when using position: absolute;, I faced this issue by using position: relative in the child element. don't need to change position: absolute to relative, just need to add in the child element look into the beneath two examples:

let toggle = document.getElementById('toggle')

toggle.addEventListener("click", () => {
 toggle.classList.toggle('change');
})
.container {
  width: 60px;
  height: 22px;
  background: #333;
  border-radius: 20px;
  position: relative;
  cursor: pointer;

}

.change .slide {
  transform: translateX(33px);
}

.slide {
  transition: 0.5s;
  width: 20px;
  height: 20px;
  background: #fff;
  border-radius: 20px;
  margin: 2px 2px;
  z-index: 100;
}

.dot {
  width: 10px;
  height: 16px;
  background: red;
  position: absolute;
  top: 4px;
  right: 5px;
  z-index: 1;
}
<div class="container" id="toggle">
  <div class="slide"></div>
  <div class="dot"></div>
</div>

This's how it can be fixed using position relative:

let toggle = document.getElementById('toggle')

toggle.addEventListener("click", () => {
 toggle.classList.toggle('change');
})
.container {
  width: 60px;
  height: 22px;
  background: #333;
  border-radius: 20px;
  position: relative;
  cursor: pointer;

}

.change .slide {
  transform: translateX(33px);
}

.slide {
  transition: 0.5s;
  width: 20px;
  height: 20px;
  background: #fff;
  border-radius: 20px;
  margin: 2px 2px;
  z-index: 100;
  
  // Just add position relative;
  position: relative;
}

.dot {
  width: 10px;
  height: 16px;
  background: red;
  position: absolute;
  top: 4px;
  right: 5px;
  z-index: 1;
}
<div class="container" id="toggle">
  <div class="slide"></div>
  <div class="dot"></div>
</div>

Sandbox here

Upvotes: 9

steven35
steven35

Reputation: 4017

Old question but this answer might help someone.

If you are trying to display the contents of the container outside of the boundaries of the container, make sure that it doesn't have overflow:hidden, otherwise anything outside of it will be cut off.

Upvotes: 101

superconnected
superconnected

Reputation: 736

z-index only applies to elements that have been given an explicit position. Add position:relative to #popupContent and you should be good to go.

Upvotes: 52

Quentin
Quentin

Reputation: 943586

The second div is position: static (the default) so the z-index does not apply to it.

You need to position (set the position property to anything other than static, you probably want relative in this case) anything you want to give a z-index to.

Upvotes: 322

RhinoWalrus
RhinoWalrus

Reputation: 3089

Opacity changes the context of your z-index, as does the static positioning. Either add opacity to the element that doesn't have it or remove it from the element that does. You'll also have to either make both elements static positioned or specify relative or absolute position. Here's some background on contexts: http://philipwalton.com/articles/what-no-one-told-you-about-z-index/

Upvotes: 65

Related Questions