Files
sam-react-prod/claudedocs/guides/mobile/[FIX-2026-02-04] mobile-zoom-panning.md
유병철 07374c826c refactor(WEB): claudedocs 재정리 및 AuthContext/Zustand/유틸 코드 개선
- claudedocs 폴더 구조 재정리: archive/sessions, guides/migration·mobile·universal-list, refactoring 분류
- 오래된 세션 컨텍스트/체크리스트 문서 정리 (아카이브 이동 또는 삭제)
- AuthContext → authStore(Zustand) 전환 시작, RootProvider 간소화
- GenericCRUDDialog 공통 다이얼로그 컴포넌트 추가
- PermissionDialog 삭제 → GenericCRUDDialog로 대체
- RankDialog/TitleDialog GenericCRUDDialog 기반으로 리팩토링
- toast-utils.ts 삭제 (미사용)
- fileDownload.ts 개선, excel-download.ts 정리
- menuStore/themeStore Zustand 셀렉터 최적화
- useColumnSettings/useTableColumnStore 기능 보강
- 세금계산서/견적/작업자화면/결재 등 소규모 개선

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-23 17:17:13 +09:00

2.5 KiB

[FIX] 모바일 핀치 줌 후 좌우 패닝 안 되는 문제

문제

  • 모바일(iOS Safari, Android Chrome 동일)에서 핀치 줌으로 확대 후 상하 스크롤은 되지만 좌우 이동(패닝)이 안 됨

원인 분석

근본 원인: 모바일 레이아웃의 app-shell 패턴

AuthenticatedLayout.tsx의 모바일 레이아웃이 자체 스크롤 컨테이너를 만들어 브라우저의 뷰포트 패닝을 가로챔.

문제가 된 3가지 요소

요소 코드 문제
부모 div 고정 높이 style={{ height: 'var(--app-height)' }} 레이아웃을 뷰포트에 가둠
main overflow overflow-y-auto / overflow-auto main을 스크롤 컨테이너로 만듦
overscroll 차단 overscroll-contain 스크롤 이벤트 전파 차단

동작 메커니즘

  1. 핀치 줌 → 브라우저 visual viewport 확대
  2. 좌우 패닝 시도 → 터치 이벤트가 <main> 스크롤 컨테이너에 도달
  3. <main>에 가로 오버플로우 콘텐츠 없음 → 스크롤 불가
  4. overscroll-behavior: contain → 브라우저 뷰포트 패닝으로 전파 차단
  5. 결과: 좌우 이동 불가

시도했지만 효과 없었던 방법들

  • touchAction: 'pan-x pan-y pinch-zoom' → 스크롤 컨테이너가 이벤트 가로채서 무효
  • touchAction: 'manipulation' → 동일
  • html { touch-action: manipulation } → 하위 스크롤 컨테이너가 우선
  • overscrollBehaviorX: auto 단독 적용 → 부모 고정 높이가 여전히 제약

해결

변경 사항

src/layouts/AuthenticatedLayout.tsx

// Before
<div className="flex flex-col bg-background min-h-screen" style={{ height: 'var(--app-height)' }}>
  ...
  <main className="flex-1 overflow-y-auto px-3 overscroll-contain" style={{ WebkitOverflowScrolling: 'touch', touchAction: 'pan-y pinch-zoom' }}>

// After
<div className="flex flex-col bg-background min-h-screen">
  ...
  <main className="flex-1 px-3">

src/app/globals.css (추가)

html {
  touch-action: manipulation;
}

핵심 원리

  • 부모 div의 height: var(--app-height) 제거 → 레이아웃이 자연스럽게 확장
  • <main>overflow-auto, overscroll-contain 제거 → 스크롤 컨테이너 해제
  • 스크롤이 body/html 레벨로 이동 → 브라우저가 줌 패닝 정상 처리

확인 사항

  • 핀치 줌 후 좌우 패닝
  • 일반 상하 스크롤
  • 헤더 sticky 유지
  • 데스크톱 레이아웃 영향 없음 (별도 분기)