Teoria
Osservando l'implementazione corrente del sito pinterest (potrebbe cambiare in futuro), quando si apre l'overlay noscroll
viene applicata una classe body
all'elemento e overflow: hidden
viene impostata, quindi body
non è più scorrevole.
La sovrapposizione (creata on-the-fly o già all'interno della pagina e reso visibile via display: block
, non fa differenza) ha position : fixed
e overflow-y: scroll
, con top
, left
, right
e bottom
le proprietà impostata 0
: questo stile rende la sovrapposizione riempire l'intera finestra.
L' div
interno della sovrapposizione è invece appena in position: static
poi la barra di scorrimento verticale che vedi è correlata a quell'elemento. Di conseguenza, il contenuto è scorrevole ma l'overlay rimane fisso.
Quando chiudi lo zoom nascondi l'overlay (tramite display: none
) e puoi anche rimuoverlo completamente tramite javascript (o solo il contenuto all'interno, dipende da te come iniettarlo).
Come passaggio finale devi anche rimuovere la noscroll
classe in body
(quindi la proprietà di overflow ritorna al suo valore iniziale)
Codice
Esempio Codepen
(funziona modificando l' aria-hidden
attributo dell'overlay per mostrarlo e nasconderlo e aumentarne l'accessibilità).
Markup
(pulsante Apri)
<button type="button" class="open-overlay">OPEN LAYER</button>
(pulsante di sovrapposizione e chiusura)
<section class="overlay" aria-hidden="true">
<div>
<h2>Hello, I'm the overlayer</h2>
...
<button type="button" class="close-overlay">CLOSE LAYER</button>
</div>
</section>
CSS
.noscroll {
overflow: hidden;
}
.overlay {
position: fixed;
overflow-y: scroll;
top: 0; right: 0; bottom: 0; left: 0; }
[aria-hidden="true"] { display: none; }
[aria-hidden="false"] { display: block; }
Javascript (vanilla-JS)
var body = document.body,
overlay = document.querySelector('.overlay'),
overlayBtts = document.querySelectorAll('button[class$="overlay"]');
[].forEach.call(overlayBtts, function(btt) {
btt.addEventListener('click', function() {
/* Detect the button class name */
var overlayOpen = this.className === 'open-overlay';
/* Toggle the aria-hidden state on the overlay and the
no-scroll class on the body */
overlay.setAttribute('aria-hidden', !overlayOpen);
body.classList.toggle('noscroll', overlayOpen);
/* On some mobile browser when the overlay was previously
opened and scrolled, if you open it again it doesn't
reset its scrollTop property */
overlay.scrollTop = 0;
}, false);
});
Infine, ecco un altro esempio in cui l'overlay si apre con un effetto di dissolvenza da un CSS transition
applicato alla opacity
proprietà. Viene inoltre padding-right
applicato un simbolo per evitare un riflusso del testo sottostante quando la barra di scorrimento scompare.
Esempio di Codepen (dissolvenza)
CSS
.noscroll { overflow: hidden; }
@media (min-device-width: 1025px) {
/* not strictly necessary, just an experiment for
this specific example and couldn't be necessary
at all on some browser */
.noscroll {
padding-right: 15px;
}
}
.overlay {
position: fixed;
overflow-y: scroll;
top: 0; left: 0; right: 0; bottom: 0;
}
[aria-hidden="true"] {
transition: opacity 1s, z-index 0s 1s;
width: 100vw;
z-index: -1;
opacity: 0;
}
[aria-hidden="false"] {
transition: opacity 1s;
width: 100%;
z-index: 1;
opacity: 1;
}