개발관련/other

본문 스크롤을 방지하지만 오버레이 스크롤은 허용

Rateye 2021. 11. 23. 10:19
728x90
반응형
질문 : 본문 스크롤을 방지하지만 오버레이 스크롤은 허용

나는 이것을 허용하는 "lightbox"유형 해결책을 찾고 있었지만 아직 하나를 찾지 못했다 (아는 것이 있다면 제안하십시오).

제가 재현하려는 동작은 이미지를 클릭 할 때 Pinterest 에서 볼 수있는 것과 같습니다. 오버레이는 스크롤 가능하지만 ( 전체 오버레이가 페이지 상단의 페이지처럼 위로 이동하는 것처럼 ) 오버레이 뒤 의 본문은 고정되어 있습니다.

CSS ( 즉, 전체 페이지 상단의 div overflow: hidden )로 만들려고했지만 div 가 스크롤되는 것을 막지는 않습니다.

본문 / 페이지가 스크롤되지 않도록하고 전체 화면 컨테이너 내에서 계속 스크롤하는 방법은 무엇입니까?

답변

이론

현재 pinterest 사이트 구현을 살펴보면 (향후 변경 될 수 있음) 오버레이를 열면 noscroll 클래스가 body 요소에 overflow: hidden 이 설정되어 body 을 더 이상 스크롤 할 수 없습니다.

오버레이 (즉석 또는 이미 페이지 내부에 생성되고 display: block 통해 표시됨)는 position : fixedoverflow-y: scroll , top , left , rightbottom 0 설정되어 있습니다. :이 스타일은 오버레이가 전체 뷰포트를 채우도록합니다.

오버레이 내부의 div position: static 이면 표시되는 수직 스크롤바가 해당 요소와 관련됩니다. 결과적으로 콘텐츠는 스크롤 가능하지만 오버레이는 고정 된 상태로 유지됩니다.

확대 / 축소를 닫을 때 오버레이를 숨기고 ( display: none 을 통해) 자바 스크립트를 통해 완전히 제거 할 수도 있습니다 (또는 내부의 콘텐츠 만 삽입 할 수 있습니다).

마지막 단계로 noscroll 클래스를 body 제거해야합니다 (오버플로 속성이 초기 값으로 반환 됨).

암호

Codepen 예

(오버레이를 표시하거나 숨기고 접근성을 높이기 위해 오버레이 aria-hidden 속성을 변경하여 작동합니다).

마크 업
(열기 버튼)

<button type="button" class="open-overlay">OPEN LAYER</button>

(오버레이 및 닫기 버튼)

<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; }

자바 스크립트 (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);

});

opacity 속성에 적용된 transition 에 의해 페이드 인 효과로 오버레이가 열리는 또 다른 예가 있습니다. 또한 스크롤바가 사라질 때 기본 텍스트에서 리플 로우를 방지하기 위해 padding-right

Codepen 예제 (페이드)

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; 
}
출처 : https://stackoverflow.com/questions/9280258/prevent-body-scrolling-but-allow-overlay-scrolling
728x90
반응형