채팅 UI에서 페이지 스크롤 방지하기: overscroll-behavior
이번 글에서는 모바일 웹, 특히 iOS Safari에서 채팅창을 만들다가 마주친 스크롤 이슈를 어떻게 해결했는지를 공유해보려고 합니다. CSS 속성인 overscroll-behavior를 통해 브라우저 전체가 스크롤되는 문제를 잡은 사례입니다.
개요
- 문제 상황: 채팅창 스크롤 시 페이지 전체가 움직이는 현상
- 스크롤 이벤트 전파 방식 이해하기
- overscroll-behavior란?
- 해결 방법과 코드 예시
- 마무리 및 정리
1. 문제 상황
iOS Safari에서 채팅 UI를 개발하던 중, 채팅창을 스크롤하면 채팅창만 스크롤되는 것이 아니라 브라우저 전체가 아래로 따라 움직이는 문제가 생겼습니다. 사용자는 채팅 영역만 터치하고 있는데, 스크롤이 문서 전체로 이어지면서 의도하지 않은 화면 튐(bounce)이 발생했던 것입니다.
스크롤이 채팅창 안에서만 멈췄으면 좋겠는데, 아래로 밀면 페이지 전체가 '툭' 튀는 느낌이 듭니다. 사용자 경험으로 보면 꽤 거슬리는 상황이었습니다.
2. 스크롤 이벤트 전파 방식 이해하기
이 문제의 원인은 스크롤 이벤트가 부모 요소로 전파된다는 브라우저의 기본 동작에 있습니다.
🧭 기본 구조를 예로 들면:
<div class="chat-container">
<ul class="chat-box">
<li class="message">안녕하세요!</li>
<!-- … -->
</ul>
</div
- 사용자가
.chat-box
에서 손가락을 위아래로 스와이프하면 스크롤 이벤트가 발생합니다. - 이때
.chat-box
의 스크롤이 끝에 도달하면, 브라우저는 이벤트를 부모 요소인main
→body
로 전파합니다. - 결국, 페이지 전체가 같이 움직이거나 bounce 되는 현상이 발생합니다.
iOS Safari에서 더 심하다?
iOS는 스크롤이 끝에 닿으면 기본적으로 바운스 효과(bounce)를 적용합니다.
스크롤이 멈췄다가도 손가락을 계속 밀면, 상위 요소가 흔들리는 듯한 느낌이 납니다.
3. overscroll-behavior란?
이럴 때 등장하는 것이 overscroll-behavior
입니다.
이 속성은 스크롤이 끝났을 때 다음 요소(부모)로 이벤트가 전달되는 걸 제어할 수 있게 해줍니다.
속성 값 | 의미 |
---|---|
auto |
기본값. 이벤트가 부모로 전달됨 |
contain |
자식 컨테이너 내부에서만 스크롤 체이닝을 막고, 브라우저 기본 바운스(예: pull-to-refresh)는 여전히 동작 |
none |
스크롤 체이닝과 함께 브라우저 바운스(pull-to-refresh, bounce) 모두 비활성화 |
overscroll-behavior
는 Chrome 63+, Firefox 59+, Edge 79+, Safari 15+ (iOS 15+) 이상부터 지원됩니다.overscroll-behavior
에 축을 설정하여 가로/세로 스크롤 제어를 구분할 수 있습니다.overscroll-behavior-y: none;
overscroll-behavior-x: contain;
4. 해결 방법과 코드 예시
✅ 적용 전 구조
.chat-container {
height: 100vh;
display: flex;
flex-direction: column;
}
.chat-box {
height: 100%;
overflow-y: auto;
}
이 상태에서는 iOS에서 채팅창 스크롤이 끝났을 때 브라우저 전체가 따라 내려갑니다.
공통적(안드로이드 및 iOS)으로는 pull-to-refresh가 발생합니다.
✅ 적용 후 구조
.chat-container {
height: 100vh;
display: flex;
flex-direction: column;
}
.chat-box {
flex: 1;
overflow-y: auto;
overscroll-behavior: none; /* 또는 overscroll-behavior-y: none; */
}
contain
을 사용할 경우에는 스크롤 이벤트가.chat-box
범위를 벗어나면 오버스크롤 효과가 발생하여 새로고침이 될 수 있습니다.- 따라서
none
을 사용하여 오버스크롤 효과를 제거하고 채팅 스크롤만 동작할 수 있게 합니다. - demo (출처: https://developer.mozilla.org/en-US/docs/Web/CSS/overscroll-behavior)를 통해서 어떻게 적용이 되는지 확인할 수 있습니다.
5. 마무리 및 정리
모바일 환경에서의 사용자 경험은 작은 디테일이 전체 완성도를 결정합니다.
특히 채팅 UI 같이 사용자가 자주 인터랙션하는 컴포넌트에서 스크롤이 튀는 문제는 꽤 불쾌하게 다가올 수 있어요.
이번 경험을 통해 느낀 점은 스크롤 이벤트의 전파 구조를 알고 있는 것만으로도 문제를 미리 예방할 수 있다는 것과 overscroll-behavior는 적은 코드로 사용자 경험을 크게 개선할 수 있는 속성이라는 것입니다.
참고 자료
- MDN: overscroll-behavior
- CSS-Tricks: Scroll Chaining vs. Overscroll-Behavior
- Can I Use: overscroll-behavior
이 글이 채팅 UI나 모바일 인터랙션을 고민하고 있는 분들에게 도움이 되었길 바랍니다 :)
감사합니다.