Học thuyết
Nhìn vào triển khai hiện tại của trang pinterest (nó có thể thay đổi trong tương lai), khi bạn mở lớp phủ, một noscroll
lớp được áp dụng cho body
phần tử và overflow: hidden
được đặt, do đó body
không thể cuộn được nữa.
Lớp phủ (tạo on-the-fly hoặc đã được bên trong trang và làm có thể nhìn thấy qua display: block
, nó làm cho không có sự khác biệt) có position : fixed
và overflow-y: scroll
, với top
, left
, right
và bottom
thuộc tính được gán 0
: phong cách này làm cho lớp phủ lấp đầy toàn bộ khung nhìn.
Thay div
vào đó, lớp phủ bên trong thay vào đó chỉ là position: static
thanh cuộn dọc mà bạn thấy có liên quan đến yếu tố đó. Kết quả là nội dung có thể cuộn được nhưng lớp phủ vẫn cố định.
Khi bạn đóng thu phóng, bạn ẩn lớp phủ (thông qua display: none
) và sau đó bạn cũng có thể xóa hoàn toàn thông qua javascript (hoặc chỉ nội dung bên trong, tùy thuộc vào cách bạn tiêm nó).
Bước cuối cùng, bạn cũng phải xóa noscroll
lớp thành body
(để thuộc tính tràn trở về giá trị ban đầu)
Mã
Ví dụ về Codepen
(nó hoạt động bằng cách thay đổi aria-hidden
thuộc tính của lớp phủ để hiển thị và ẩn nó và để tăng khả năng truy cập của nó).
Đánh dấu
(nút mở)
<button type="button" class="open-overlay">OPEN LAYER</button>
(lớp phủ và nút đóng)
<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);
});
Cuối cùng, đây là một ví dụ khác trong đó lớp phủ mở ra với hiệu ứng mờ dần bởi CSS transition
được áp dụng cho thuộc opacity
tính. Ngoài ra a padding-right
được áp dụng để tránh hiện tượng chỉnh lại dòng chữ bên dưới khi thanh cuộn biến mất.
Ví dụ Codepen (fade)
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;
}