1

I'm setting up a popup modal with a open button inside a parent div, but when it opens, it is contained inside the div, and I want it to open on top of all the divs.

I've tried setting the z-index higher than the parent div, but it doesn't seem to make a difference. I suspect it has something to do with the placement of the parent div, which is positioned absolute middle and center inside its own parent div. If I take the modal out of the divs, it opens in full screen like I need it to.

<div id="parent1" style="position:relative;height:100%;z-index:1;">
  <div id="parent2" style="position:absolute;top:50%;left:50%;transform:translate(-50%,-50%);text-align:center;width:100%;z-index:2;">
    (modal, which is set to z-index:3)
  </div>
</div>
nckclsn
  • 13
  • 1
  • 3
  • Possible duplicate of [Absolute positioning inside absolute position](https://stackoverflow.com/questions/5928059/absolute-positioning-inside-absolute-position) – Lewis Apr 30 '19 at 15:59

2 Answers2

1

You have wrapped your absolute div inside a position relative div. That's why it is inside. The snippet below will tell you how relative and absolute positioning works together.

  .top {
  top: 50px;
  height: 100%;
  position: relative;
}

.relative {
  background: #dfdfdf;
  ) body {
    height: 100%;
  }
  .absolute {
    position: absolute;
    bottom: 0;
  }
<div class="relative top">
  <div class="absolute bottom">hey there</div>
</div>

The div is supposed to go all the way down, but no as it is wrapped by a div which is relative, if you remove the relative class, then the div will fall down.
For a modal that covers the whole page, use position fixed or absolute outside any relative div, or even better -> use a flexbox for a "very responsive" modal

document.getElementById('modal-Opener').onclick = function() {
  document.querySelector('.modal').classList.add("modalOpen");
}
body,
html {
  height: 100%
}

.modal {
  border-radius: 20px;
  height: 100px;
  background-color: #dfdfdf;
  width: 60%;
  color: #000;
  padding: 20px;
  display: none;
  position: relative;
  justify-content: center;
  -webkit-animation-name: animatetop;
  -webkit-animation-duration: 0.4s;
  animation-name: animatetop;
  animation-duration: 0.4s align-items:center;
}

.modalOpen {
  display: flex;
}

.flex {
  height: 100%;
  display: flex;
  justify-content: center;
  align-items: center;
  align-self: center;
}

@-webkit-keyframes animatetop {
  from {
    top: -300px;
    opacity: 0
  }
  to {
    top: 0;
    opacity: 1
  }
}

@keyframes animatetop {
  from {
    top: -300px;
    opacity: 0
  }
  to {
    top: 0;
    opacity: 1
  }
}
<button id="modal-Opener">Open modal</button>
<div class='flex'>
  <div class='modal'>I am a modal</div>
</div>
weegee
  • 3,256
  • 2
  • 18
  • 32
  • Thank you for your answer. If I remove the relative class, then the link to open the modal goes in a completely wrong position. The problem is, I want it to be centered both vertically and horizontally (the link to open the modal), and I had to use the absolute div inside the relative div to attain that. Is there another way? – nckclsn Apr 30 '19 at 16:29
  • I used a flexbox for both centering both vertically and horizontally, try me example – weegee Apr 30 '19 at 16:30
  • I'm not familiar with flexbox and I can't seem to make your example work. I might be in over my head here. I don't suppose you can tell me what I'm missing without wasting too much of your time? – nckclsn Apr 30 '19 at 16:51
  • Copy my HTML and CSS and place it inside the body tag, remember, inside the body tag, not any other div just for testing. The flex will only work if the height is 100% – weegee Apr 30 '19 at 16:53
  • Seems to work: https://nickclausenbooks.com/new/test.htm Does a flexbox modal open with the same trigger as this one which I used: https://www.w3schools.com/howto/howto_css_modals.asp ? – nckclsn Apr 30 '19 at 17:01
  • Awesome, thank you! Changed to flex, that's seems a lot better and easier. But still, the modal opens in my div-column and not on the full screen, do you happen to know why? – nckclsn Apr 30 '19 at 18:11
  • What do you mean by div-column? – weegee Apr 30 '19 at 18:13
0

If I understand correctly, you want the following:

  • link to open the modal centered vertically and horizontally on the page (taking up only the space it needs to vertically and horizontally)
  • modal to open full screen on the whole page (taking up all space vertically and horizontally)

If that is correct, then you need:

  • a parent div to contain the link to open the modal, but not the modal itself
  • a modal div set to fixed so it applies to the viewport (visible screen) no matter which div it is inside

CSS tips and tricks to note:

  • display:flex is the easiest and most robust way to center content horizontally and/or vertically (unless you need to support legacy browsers)
  • position:fixed applies to the viewport (visible screen area) no matter where the element is in the page flow, so you can place the modal div wherever you want
  • position:absolute restricts the element to its parent, so you would need to place the modal div as a child of body or #parent1 (depending on what you mean by "full screen") instead of #parent2
  • z-index is usually needed when an element that comes earlier in the document flow needs to show up above elements that come later in the document flow. If you can change around the order of the elements, that's the safer approach. z-index can get hard to track and debug when too many are used all over a document.

The example below uses colored borders to better visualize where the divs are spatially. Click on the button to show the modal. Click on the modal to close the modal.

//using jquery for convenience; can be done with javascript or css only instead
$(document).ready(function() {
  let modal = $('#modal');

  //show modal
  $('#link_to_modal').on('click', function() {
    modal.css('display', 'block');
  });

  //hide modal
  modal.on('click', function() {
    modal.css('display', 'none');
  });
});
#parent1 {
  position: relative;
  height: 300px; /* 100% for actual, 300px for testing */
  border: 1px solid blue;
  display: flex;
  justify-content: center;
  align-items: center;
}

#parent2 {
  border: 1px solid red;
}

#modal {
  position: fixed;
  top: 0;
  right: 0;
  bottom: 0;
  left: 0;
  border: 1px solid green;
  background-color: white;
  display: none;
  overflow-y: auto;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="parent1">
  <div id="parent2">
    <button id="link_to_modal" type="button">Open Modal</button>
    <div id="modal">Modal in full screen</div>
  </div>
</div>
OXiGEN
  • 2,041
  • 25
  • 19
  • The user never mentioned if they are using jquery – weegee Apr 30 '19 at 17:16
  • @window.document Good point. Updated to clarify JS component about using jQuery for ease and other options exist. The JS component is not directly relevant to his question and not even necessary for CSS only modal implementations. – OXiGEN Apr 30 '19 at 18:22