Prevent scroll below modal window on iOS

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

Demo Download

AuthorTigran Sargsyan
CreatedSEPTEMBER 15, 2018
LicenseOpen
Compatible browsersChrome, 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 1

W3TWEAKS
Latest posts by W3TWEAKS (see all)

Comments

Leave a Reply

Your email address will not be published. Required fields are marked *