How to prevent scrolling further down from modal?

Viewed 170

I have a modal which is taller than the screen but less tall than the rest of the page. I want users to be able to scroll within this modal but not within the page.

So they shouldn't be able to go further down than the bottom edge of the modal (even though underneath the modal the page does indeed continues because it's much taller than the modal). Basically, all they should be able to see through scrolling up or down is the modal.

Is there a simple way to achieve this with CSS? If not, with CSS + JS?

Note: I tried several things including to calculate the height of the modal with JS and apply that height to the HTML element, but I'm not sure where to go from there.

Codepen

HTML:

<body>
  <div class="modal"></div>
  <div class="content"></div>
</body>

CSS:

body {
  background: blue;
}

.content {
  background: red;
  height: 3000px;
}

.modal {
  position: absolute;
  top: 50px;
  left: 50px;
  right: 50px;
  background: yellow;
  height: 1300px;
}
4 Answers

i did not quite understand you question but if you want the model to be at certain height and to see the content it have you gotta scroll , see this code which i set the height of modal to be 300px so to see the rest of content inside it you scroll and not pass the bottom of the page

body {
  background: blue;
}

.modal {
  position: absolute;
  top: 50px;
  left: 50px;
  right: 50px;
  height: 300px;
  overflow-y: scroll;
}
.content {
 height : 3000px ; 
 background : red ; 
}
<body>
  <div class="modal">
    <div class="content">
      <h1>yo</h1>
      <h1>yo</h1>
      <h1>yo</h1>
      <h1>yo</h1>
      <h1>yo</h1>
      <h1>yo</h1>
      <h1>yo</h1>
      <h1>yo</h1>
      <h1>yo</h1>
      <h1>yo</h1>
      <h1>yo</h1>
      <h1>yo</h1>
      <h1>yo</h1>
      <h1>yo</h1>
      <h1>yo</h1>
      <h1>yo</h1>
      <h1>yo</h1>
      <h1>yo</h1>
      <h1>yo</h1>
      <h1>yo</h1>
      <h1>yo</h1>
      <h1>yo</h1>
      <h1>yo</h1>
      <h1>yo</h1>
      <h1>yo</h1>
      <h1>yo</h1>
      <h1>yo</h1>
      <h1>yo</h1>
      <h1>yo</h1>
      <h1>yo</h1>
      <h1>yo</h1>
      <h1>yo</h1>
      <h1>yo</h1>
      <h1>yo</h1>
      <h1>yo</h1>
      <h1>yo</h1>
      <h1>yo</h1>
      <h1>yo</h1>
      <h1>yo</h1>
      <h1>yo</h1>
      <h1>yo</h1>
      <h1>yo</h1>
    </div>
  </div>
</body>

I don't know any solution for this that uses just css, but here's how you can do it with JS. CodePen

let modalIsOpen = true;
let btn = document.querySelector('#btn');
let modal = document.querySelector('.modal');
let content = document.querySelector('body');


btn.addEventListener('click', ()=>{
  if(modalIsOpen){
    modal.style.display = 'block';
    content.style.overflow = 'hidden';
  } else {
    modal.style.display = 'none';
    content.style.overflow = 'auto';
  }
    modalIsOpen = !modalIsOpen;
})
body {
  background: blue;
}

.content {
  background: red;
  height: 3000px;
}

.modal {
  position: absolute;
  top: 50px;
  left: 50px;
  right: 50px;
  background: yellow;
  height: 1300px;
  overflow: scroll;
  display: none;
}
<body>
  <button id='btn'>Toggle Modal</button>
  <div class="modal"></div>
  <div class="content"></div>
</body>

Just check if the modal is open, if so hide the overflow of the body which prevents the user from scrolling.

Edit I think you should wrap your modal, like so:

.modalWrap{
  position: absolute;
  top:0;
  right: 0;
  height: 100%;
  width: 100%;
}

This acts as the scrollable container, take a look at w3schools tutorial on modals to get a better idea.

Edit 3 I've added a modal container. JsFiddle

let modalIsOpen = false;
let btn = document.querySelector('#btn');
let modalWrap = document.querySelector('.modalWrap');
let content = document.querySelector('body');


btn.addEventListener('click', ()=>{
  if(modalIsOpen){
    modalWrap.style.display = 'flex';
    content.style.overflow = 'hidden';
  } else {
    modalWrap.style.display = 'none';
    content.style.overflow = 'auto';
  }
    modalIsOpen = !modalIsOpen;
})
body {
  background: blue;
}

button{
    z-index: 2;
    position: absolute;
    top: 2px;
    left: 2px;
}

.content {
  background: red;
  height: 3000px;
}

.modalWrap{
  position: fixed;
  top: 0;
  left: 0;
  height: 100%;
  width: 100%;
  display: none;
  overflow: auto;
  z-index: 1;
  padding: 50px;
  box-sizing: border-box;
  background-color: rgba(0,0,0,0.4);
}

.modal {
  background: yellow;
  position: relative;
  height: 2300px;
  top: 5px;
  width: 80%;
  margin: 0 auto;
}
<body>
  <button id='btn'>Toggle Modal</button>
  <div class='modalWrap'>
    <div class="modal"></div>  
  </div>
  <div class="content"></div>
</body>

When you have the modal open, the body scrolling is disabled, so you don't get multiple scroll bars. The modalWrap acts as the container for the modal and it's the one getting scrolled, the modal can be any height as needed.

I think this will help, as I made modal where when modal gets open the verticle scrolling in body is hidden, and overflowing content of modal can be scrolled.

$(document).ready(function() {
  $('.modal-toggle').on('click', function() {
    $('.modal').toggleClass('is-visible');
    $('body').toggleClass('modal-is-open');
  });
});
body.modal-is-open {
  overflow-y: hidden;
}

a {
  text-decoration: none;
  outline: none;
}

.modal {
  display: inline-block;
  background-color: #a3c62c;
  position: absolute;
  max-width: calc(100% - 30px);
  top: 15px;
  left: 15px;
  right: 15px;
  opacity: 0;
  visibility: hidden;
  height: 80vh;
  overflow-y: scroll;
}

.modal.is-visible {
  opacity: 1;
  visibility: visible;
  z-index: 9;
}

.modal-toggle {
  position: relative;
  background-color: #fff;
  padding: 5px;
  box-shadow: 0 0 10px 0 rgba(0, 0, 0, 0.3);
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

<body>
  <div class="modal">
    <a href="#" class="modal-toggle">close modal
    </a>
    <p>
      There are many variations of passages of Lorem Ipsum available, but the majority have suffered alteration in some form, by injected humour, or randomised words which don't look even slightly believable. If you are going to use a passage of Lorem Ipsum,
      you need to be sure there isn't anything embarrassing hidden in the middle of text. All the Lorem Ipsum generators on the Internet tend to repeat predefined chunks as necessary, making this the first true generator on the Internet. It uses a dictionary
      of over 200 Latin words, combined with a handful of model sentence structures, to generate Lorem Ipsum which looks reasonable. The generated Lorem Ipsum is therefore always free from repetition, injected humour, or non-characteristic words etc.
      There are many variations of passages of Lorem Ipsum available, but the majority have suffered alteration in some form, by injected humour, or randomised words which don't look even slightly believable. If you are going to use a passage of Lorem
      Ipsum, you need to be sure there isn't anything embarrassing hidden in the middle of text. All the Lorem Ipsum generators on the Internet tend to repeat predefined chunks as necessary, making this the first true generator on the Internet. It uses
      a dictionary of over 200 Latin words, combined with a handful of model sentence structures, to generate Lorem Ipsum which looks reasonable. The generated Lorem Ipsum is therefore always free from repetition, injected humour, or non-characteristic
      words etc. There are many variations of passages of Lorem Ipsum available, but the majority have suffered alteration in some form, by injected humour, or randomised words which don't look even slightly believable. If you are going to use a passage
      of Lorem Ipsum, you need to be sure there isn't anything embarrassing hidden in the middle of text. All the Lorem Ipsum generators on the Internet tend to repeat predefined chunks as necessary, making this the first true generator on the Internet.
      It uses a dictionary of over 200 Latin words, combined with a handful of model sentence structures, to generate Lorem Ipsum which looks reasonable. The generated Lorem Ipsum is therefore always free from repetition, injected humour, or non-characteristic
      words etc. There are many variations of passages of Lorem Ipsum available, but the majority have suffered alteration in some form, by injected humour, or randomised words which don't look even slightly believable. If you are going to use a passage
      of Lorem Ipsum, you need to be sure there isn't anything embarrassing hidden in the middle of text. All the Lorem Ipsum generators on the Internet tend to repeat predefined chunks as necessary, making this the first true generator on the Internet.
      It uses a dictionary of over 200 Latin words, combined with a handful of model sentence structures, to generate Lorem Ipsum which looks reasonable. The generated Lorem Ipsum is therefore always free from repetition, injected humour, or non-characteristic
      words etc. There are many variations of passages of Lorem Ipsum available, but the majority have suffered alteration in some form, by injected humour, or randomised words which don't look even slightly believable. If you are going to use a passage
      of Lorem Ipsum, you need to be sure there isn't anything embarrassing hidden in the middle of text. All the Lorem Ipsum generators on the Internet tend to repeat predefined chunks as necessary, making this the first true generator on the Internet.
      It uses a dictionary of over 200 Latin words, combined with a handful of model sentence structures, to generate Lorem Ipsum which looks reasonable. The generated Lorem Ipsum is therefore always free from repetition, injected humour, or non-characteristic
      words etc. There are many variations of passages of Lorem Ipsum available, but the majority have suffered alteration in some form, by injected humour, or randomised words which don't look even slightly believable. If you are going to use a passage
      of Lorem Ipsum, you need to be sure there isn't anything embarrassing hidden in the middle of text. All the Lorem Ipsum generators on the Internet tend to repeat predefined chunks as necessary, making this the first true generator on the Internet.
      It uses a dictionary of over 200 Latin words, combined with a handful of model sentence structures, to generate Lorem Ipsum which looks reasonable. The generated Lorem Ipsum is therefore always free from repetition, injected humour, or non-characteristic
      words etc. There are many variations of passages of Lorem Ipsum available, but the majority have suffered alteration in some form, by injected humour, or randomised words which don't look even slightly believable. If you are going to use a passage
      of Lorem Ipsum, you need to be sure there isn't anything embarrassing hidden in the middle of text. All the Lorem Ipsum generators on the Internet tend to repeat predefined chunks as necessary, making this the first true generator on the Internet.
      It uses a dictionary of over 200 Latin words, combined with a handful of model sentence structures, to generate Lorem Ipsum which looks reasonable. The generated Lorem Ipsum is therefore always free from repetition, injected humour, or non-characteristic
      words etc.
    </p>
  </div>
  <div class="content">
    <a href="#" class="modal-toggle">open modal</a>
    <p>
      There are many variations of passages of Lorem Ipsum available, but the majority have suffered alteration in some form, by injected humour, or randomised words which don't look even slightly believable. If you are going to use a passage of Lorem Ipsum,
      you need to be sure there isn't anything embarrassing hidden in the middle of text. All the Lorem Ipsum generators on the Internet tend to repeat There are many variations of passages of Lorem Ipsum available, but the majority have suffered alteration
      in some form, by injected humour, or randomised words which don't look even slightly believable. If you are going to use a passage of Lorem Ipsum, you need to be sure there isn't anything embarrassing hidden in the middle of text. All the Lorem
      Ipsum generators on the Internet tend to repeat There are many variations of passages of Lorem Ipsum available, but the majority have suffered alteration in some form, by injected humour, or randomised words which don't look even slightly believable.
      If you are going to use a passage of Lorem Ipsum, you need to be sure there isn't anything embarrassing hidden in the middle of text. All the Lorem Ipsum generators on the Internet tend to repeat There are many variations of passages of Lorem Ipsum
      available, but the majority have suffered alteration in some form, by injected humour, or randomised words which don't look even slightly believable. If you are going to use a passage of Lorem Ipsum, you need to be sure there isn't anything embarrassing
      hidden in the middle of text. All the Lorem Ipsum generators on the Internet tend to repeat There are many variations of passages of Lorem Ipsum available, but the majority have suffered alteration in some form, by injected humour, or randomised
      words which don't look even slightly believable. If you are going to use a passage of Lorem Ipsum, you need to be sure there isn't anything embarrassing hidden in the middle of text. All the Lorem Ipsum generators on the Internet tend to repeat
      There are many variations of passages of Lorem Ipsum available, but the majority have suffered alteration in some form, by injected humour, or randomised words which don't look even slightly believable. If you are going to use a passage of Lorem
      Ipsum, you need to be sure there isn't anything embarrassing hidden in the middle of text. All the Lorem Ipsum generators on the Internet tend to repeat
    </p>
  </div>
</body>

I think giving the modal a height: 1300px does not make it scrollable automatically. You still need to declare overflow-y: scroll.

Related