Prevent scroll below modal window on iOS

Prevent scroll below modal window on iOS developed using CSS, HTML. Demo and Download available.

Demo Download

Author Tigran Sargsyan
Hits
Created SEPTEMBER 15, 2018
License Open
Compatible browsers Chrome, Firefox, Safari

HTML Snippet

</p>
    <p>page can scroll...</p>
    <p>page can scroll...</p>
    <p>yes it can!</p>    
        
</article><input type="checkbox" id="toggleModal" />

<article>
    <h1>Prevent scroll below modal window on iOS <span>(99%)</span></h1>
    <hr />
    <p>Creating websites that works on iOS is...</p>
    <h2>Super relaxing</h2>
    <img src="https://us-east-1.tchyn.io/snopes-production/uploads/2016/05/monsters-inc.jpg" />   
    <label for="toggleModal">Open modal<i  class="material-icons">launch</i></label>
    <p>page can scroll...</p>
    <hr />    
    <h2>Pure joy</h2>    
    <img src="https://i.ytimg.com/vi/dJWm0TWH7d0/maxresdefault.jpg" />
    <label for="toggleModal">Open modal<i  class="material-icons">launch</i></label>    
    <p>page can scroll...</p>
    <p>page can scroll...</p>
    <p>page can scroll...</p>
    
    <hr />    
    <h2>No struggle at all</h2>
    <img src="https://pixar-planet.fr/wp-content/uploads/2010/04/george-sanderson-personnage-monstres-cie-04.jpg" />
    <label for="toggleModal">Open modal<i  class="material-icons">launch</i></label>        
    <p>page can scroll...


<label for="toggleModal"><i  class="material-icons">close</i></label>       
<div class="modal">
<article>
    <h2>Feel free to scroll again</h2>
    <p>modal can scroll...</p>
    <p>modal can scroll...</p>
    <p>modal can scroll...</p>
    <p>modal can scroll...</p>
    <p>modal can scroll...</p>
    <p>modal can scroll...</p>
    <p>modal can scroll...</p>
    <p>modal can scroll...</p>
    <p>modal can scroll...</p>
    <p>modal can scroll...</p>
    <p>modal can scroll...</p>
    <p>modal can scroll...</p>
    <p>modal can scroll...</p>
    <p>modal can scroll...</p>
    <p>modal can scroll...</p>
    <p>modal can scroll...</p>
    <p>modal can scroll...</p>
    <p>modal can scroll...</p>
    <p>modal can scroll...</p>
    <p>modal can scroll...</p>
    <p>modal can scroll...</p>
    <p>modal can scroll...</p>
    <p>modal can scroll...</p>
    <p>modal can scroll...</p>
    <p>modal can scroll...</p>
    <p>modal can scroll...</p>
    <a href="#" onclick="alert('ðߑ»ðߑ»ðߑ»ðߑ»ðߑ»')">You can click me if you like</a>
    <p>modal can scroll...</p>
    <p>modal can scroll...</p>
    <p>modal can scroll...</p>
    <p>modal can scroll...</p>
    <p>modal can scroll...</p>
    <p>modal can scroll...</p>
    <p>modal can scroll...</p>
    <p>modal can scroll...</p>
    <p>modal can scroll...</p>
    <p>modal can scroll...</p>
    <p>OK stop it!</p>   
    <img src="https://moviefavourites.files.wordpress.com/2010/12/mike.jpg" />
</article>

CSS Code


//  just some styling
@import url("https://fonts.googleapis.com/css?family=Merriweather:300|Open+Sans:400|Material+Icons");
html { box-sizing: border-box; } *,*::before,*::after { box-sizing: inherit; position: relative; }
body { margin: 0;}
img { border-radius: 5px; }
body {-webkit-font-smoothing: antialiased; }
h1,h2 {font-family: Merriweather, serif}
h1 {font-size: 24px;  }
h2 {font-size: 18px; }
p,label { font-family: 'Open Sans' }
p { color: #ccc; }
img { width: 100%; }
body {background: whitesmoke; }
hr { border: 0; border-top: 1px solid #ccc; }
article { padding: 20px; border-radius: 5px; background: white; box-shadow: 2px 2px 5px rgba(0,0,0,0.3); max-width: 420px; margin: 16px auto; }
label   { display: block; width: 100%; border-radius: 5px; background-color: dodgerblue; color: white; padding: 8px; cursor: pointer; }
label i { vertical-align: bottom; float: right; }
h1 span {font-size: 40%; color: #ccc;}
[id="toggleModal"]{position:fixed;left:-20px; visibility: hidden; }
[id="toggleModal"]:not(:checked) ~ .modal,
[id="toggleModal"]:not(:checked) ~ label{ display: none; }
.modal { 

    padding: 10px;
    background: rgba(0,0,0,0.7);
    position: fixed; top: 0; right: 0; bottom: 0; left: 0; 
    overflow: scroll;
    -webkit-overflow-scrolling: touch;
}

body > label { 
    position: fixed; top: 40px; right: 40px; width: auto; 
    z-index:1;
}

JavaScript Snippet

//  ââââââââââââââââââââââââââââââââââââââââââââââââââââââââ
//  Note! I'm still experimenting â code could change
//
//  A not 100% bulletproof attempt to prevent iOS from 
//  page content below modal window while allowing scroll
//  inside the modal itself.
//
//  ðߏ� Does not require position fixed or overflow  
//     hidden on the body tag  
//
//  ––––––––––––––––––––––––––––––––––––––––––––––––––––––––
(IIFE => {
    const check = document.querySelector('input');
    const modal = document.querySelector('.modal');
    
    //  prevent page scroll   
    let scrollLock = false;

    //  toggle scroll lock state 
    check.addEventListener('change', e => { scrollLock = e.target.checked });

    //  modal window listeners 
    modal.addEventListener('touchstart', onePixelHack, { passive: false }); 
    modal.addEventListener('scroll', onePixelHack, { passive: false });     
    
    //  One pixel hack 
    //  it seems iOS won't allow scrolling in modal if at top or bottom
    //  – why in that case we shift scrollTop by one pixel (up or down) 
    function onePixelHack(e){
        if(!scrollLock) return;
        const atTop = modal.scrollTop === 0;
        const atBot = modal.scrollHeight - modal.scrollTop === modal.offsetHeight;
        if(atTop||atBot){ modal.scrollTop += atTop ? 1 : -1; e.preventDefault(); }
    }
    
    //  About the passive event option:
    //  As the browser does not know if an event will be cancled it needs to 
    //  run the entire handler script before proceeding. Setting passive
    //  to true tells the browser the handler will not cancel the event and
    //  can proceed without awaiting execution. 
    //    
    //  In this case we want to cancel and as iOS 11.1 by default sets passive 
    //  to true on touchstart and touchmove we need to override it. 
})();

Preview

Prevent scroll below modal window on iOS preview

Advertisement

Google Matched Content...