skip to Main Content

I try to create a menu that pops up over the page. The height of the menu is variable and could be greater than the viewport and/or the page content. Here is simplified code:

* {
  margin: 0;
}

#overlay {
  min-height: 100%;
  width: 100%;
  position: fixed;
  background: rgba(0, 0, 0, 0.7);
  display: flex;
  align-items: start;
  justify-content: center;

}

#popup {
  margin: 50px;
  height: 50vh;
  width: 300px;
  border: 1px solid red;
  background-color: blue;
}
<div id="overlay">
  <div id="popup">
  </div>
</div>

<div id="content">
  Page content
</div>

When the page content is greater than the viewport height, the user can scroll the page even when the overlay is on the screen:

https://jsfiddle.net/Imabot/ydmwLo2j/1/

On the other hand, when the menu is greater than the viewport height the user can’t scroll to see the bottom of the menu:

https://jsfiddle.net/Imabot/ydmwLo2j/2/

I already try many stuff with overflow: scroll;. But nothing works.

Any solution to solve both issues?

I already read this question, but it does not help: How to make the height REALLY 100%

3

Answers


  1. When the modal opens, set overflow: hidden on the <body> element of the page. This will prevent scrolling when the page is taller than the viewport. Add a maximum height to the modal container to make its content scrollable when it is taller than the viewport.

    const popupContent = document.querySelector('.js-popup-content');
    const content = document.getElementById('content');
    
    document.querySelector('.js-demo-0').addEventListener('click', () => {
      popupContent.style.height = '50vh';
      content.style.height = '200vh';
    });
    
    document.querySelector('.js-demo-1').addEventListener('click', () => {
      popupContent.style.height = '200vh';
      content.style.height = '50vh';
    });
    * {
      margin:0;
    }
    
    body {
      overflow: hidden;
    }
    
    #overlay {
      min-height: 100%;
        width: 100%;
        position: fixed;
        background: rgba(0, 0, 0, 0.7);
        display: flex;
        align-items: start;
        justify-content: center;
        
    }
    
    #popup {
      margin: 50px;
      max-height: calc(100vh - 100px);
      width: 300px;
      border: 1px solid red;
      background-color: blue;
      overflow-y: auto;
    }
    
    .demo-buttons {
      position: fixed;
      z-index: 1;
      left: 1em;
      top: 1em;
    }
    <div id="overlay">
      <div id="popup">
        <div class="js-popup-content"></div>
      </div>
    </div>
    
    <div class="demo-buttons">
      <button class="js-demo-0">Short popup, long content</button>
      <button class="js-demo-1">Long popup, short content</button>
    </div>
    
    <div id="content">
      Page content
    </div>
    Login or Signup to reply.
  2. I gave min-height:100vh and position:relative values to #overlay id .In html file i put all code in to the #content id. I added background color to #content and removed #overlay‘s background color. Changed #content‘s height to 300vh.

    You can control it with codepen: https://codepen.io/yusufdogandev/pen/ZEqWvVe

    * {
      margin:0;
    }
    #overlay {
        min-height: 100vh;
        width: 100%;
        position: relative;
        display: flex;
        align-items: start;
        justify-content: center;
        text-align:left;
        
    }
    
    #popup {
      margin: 50px;
      height:200vh;
      width: 300px;
      border: 1px solid red;
      background-color: blue;
      
    }
    
    #content {
      height: 300vh;
      background: #4c4c4cb4;
    }
    <div id="content">
    Page content
    <div id="overlay">
    
      <div id="popup">
      </div>
    </div>
    
    </div>
    Login or Signup to reply.
  3. Just add to the overlay:

    height: 100%;
    overflow: auto;
    

    Since the overlay cover the entire page, the scroll bar will be apply to the overlay only : https://jsfiddle.net/65na8hy3/

    To prevent scrolling the main content, add:

    body {
    overflow: hidden;
    }

    Kill two birds with one stone, as you expected.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search