<dialog> 요소를 showModal()를 사용하여 모달로 열면 브라우저가 이를 최상위 레이어로 승격하고 나머지 문서를 비활성으로 표시합니다. 이렇게 하면 기본 페이지에서 포인터 클릭과 키보드 포커스가 차단되지만 스크롤은 차단되지 않습니다.
- 포인터 또는 터치 동작이
::backdrop위에 있는 동안 스크롤하면 아래 페이지가 스크롤됩니다. - 대화상자가 스크롤 경계에 도달하면
<dialog>내에서 스크롤이 기본 페이지로 연결됩니다. 대화상자의 콘텐츠가 오버플로되지 않는 경우에는 즉시 연결됩니다.
CSS 오버스크롤 동작 사양에 따라 overscroll-behavior는 스크롤할 수 없는 스크롤 컨테이너(overflow: hidden가 있는 요소 또는 현재 콘텐츠가 오버플로되지 않는 overflow: auto)를 포함한 모든 스크롤 컨테이너 요소에 적용됩니다. <dialog>의 overscroll-behavior: contain를 overflow: hidden 및 dialog::backdrop의 overscroll-behavior: contain와 결합하면 순수 CSS를 사용하여 기본 페이지가 스크롤되지 않도록 할 수 있습니다.
구현
1. <dialog>에 스크롤 체이닝 포함
사용자 에이전트 스타일시트는 <dialog>에 overflow: auto를 설정하여 기본적으로 스크롤 컨테이너로 만듭니다. dialog:modal(또는 dialog)에 overscroll-behavior: contain(또는 none)를 적용합니다.
2. ::backdrop를 스크롤 컨테이너로 변환하고 스크롤 포함
기본적으로 dialog::backdrop에는 overflow: visible가 있습니다. 즉, 스크롤 컨테이너가 아니며 overscroll-behavior를 무시합니다. dialog::backdrop에서 overflow: hidden를 설정하여 스크롤할 수 없는 스크롤 컨테이너로 만들고 overscroll-behavior: contain와 페어링해야 합니다. 그러면 배경에서 실행되는 스크롤 동작이 트랩되어 아래의 문서에 도달하지 않습니다.
예시 코드
dialog:modal {
/* MANDATORY: Prevent scroll gestures inside the modal (even when its content
does not overflow) from chaining to the underlying page. */
overscroll-behavior: contain;
}
dialog::backdrop {
/* MANDATORY: ::backdrop defaults to overflow: visible (not a scroll container).
Set overflow: hidden so it becomes a non-scrollable scroll container that
honors overscroll-behavior. */
overflow: hidden;
overscroll-behavior: contain;
}
권장사항 및 제약 조건
- 필수:
<dialog>요소 자체(dialog:modal선택자 사용)와dialog::backdrop에overscroll-behavior: contain를 설정합니다. 이 선언이 없으면 배경 또는 대화상자 내부의 스크롤 동작이 페이지에 계속 연결됩니다. - 필수:
dialog::backdrop에서overflow: hidden(또는overflow: auto)를 설정하여 스크롤 컨테이너가 되도록 합니다. 이 선언이 없으면::backdrop는 기본적으로overflow: visible로 설정되고overscroll-behavior는 아무런 영향을 미치지 않습니다. dialog::backdrop또는dialog에서overflow: clip또는overflow: visible를 사용하지 마세요. 두 값 모두 스크롤 컨테이너를 설정하지 않으므로overscroll-behavior이 적용되지 않습니다.- 대화상자가 열릴 때 배경 스크롤을 잠그기 위해
<html>또는<body>에overflow: hidden또는position: fixed를 적용하지 마세요. 루트 오버플로를 변경하면 페이지 스크롤바가 삭제되고 (가로 레이아웃 변경 발생) 페이지 스크롤 위치가 재설정되거나 이동할 수 있으며 기본 페이지의position: sticky요소가 손상될 수 있습니다.
대체 전략
overscroll-behavior CSS 속성은 콘텐츠가 오버플로되는 스크롤 컨테이너의 모든 주요 브라우저에서 지원되지만, 스크롤할 수 없는 스크롤 컨테이너에서 overscroll-behavior를 적용하는 것은 기능을 감지할 수 없는 최신 사양입니다.
@supports (overscroll-behavior: contain) 또는 CSS.supports('overscroll-behavior', 'contain')를 사용하여 스크롤할 수 없는 컨테이너 지원을 기능 감지하려고 시도하지 마세요. 모든 최신 브라우저는 overscroll-behavior: contain 속성 문법을 지원하며 콘텐츠가 오버플로될 때만 적용하더라도 true를 반환합니다.
대신 스크롤할 수 없는 스크롤 컨테이너의 스크롤 포함을 점진적 개선으로 처리하세요.
- 스크롤할 수 없는 스크롤 컨테이너에서
overscroll-behavior를 지원하는 브라우저에서는dialog::backdrop위와<dialog>내부에서 배경 페이지 스크롤이 완전히 차단됩니다(콘텐츠가 오버플로되는지 여부와 관계없음). - 스크롤할 수 없는 스크롤 컨테이너에서
overscroll-behavior를 아직 지원하지 않는 브라우저에서는 대화상자의 자체 콘텐츠가 오버플로되고 스크롤할 수 있을 때마다dialog의overscroll-behavior: contain가 스크롤 체이닝을 방지합니다. 한편showModal()는 여전히 키보드 포커스를 가두고 배경 문서inert를 표시합니다. <html>또는<body>에overflow: hidden또는position: fixed를 적용하는 기존 해결 방법보다는 점진적 개선을 사용하는 것이 좋습니다. 루트 스크롤바를 삭제하거나, 가로 레이아웃 변경을 일으키거나, 페이지 스크롤 위치를 이동하거나, 기본 페이지의position: sticky요소를 손상시키지 않기 때문입니다.