diff --git a/src/App.vue b/src/App.vue index e79d3a6..0f5fe64 100644 --- a/src/App.vue +++ b/src/App.vue @@ -230,7 +230,10 @@ watch(() => route.fullPath, () => ui.closeSidebar()) 'bottom bottom'; grid-template-columns: 220px 1fr; grid-template-rows: auto 1fr auto; - min-height: 100vh; + /* 앱 셸: 뷰포트 높이에 고정하고 본문(layout-body)만 스크롤 → 상단 헤더·하단 내비 고정, 페이지 전체 스크롤 방지 */ + height: 100vh; /* 폴백 */ + height: 100dvh; /* 동적 뷰포트(주소창·안전영역 반영) */ + overflow: hidden; } .layout-top { @@ -394,9 +397,11 @@ watch(() => route.fullPath, () => ui.closeSidebar()) .layout-body { grid-area: body; padding: 1.5rem 2rem; - /* 하단 고정 내비(56px)+소프트키 인셋만큼 비워 콘텐츠가 가리지 않게 */ - padding-bottom: calc(56px + env(safe-area-inset-bottom, 0) + 1rem); - overflow: auto; + /* 그리드 1fr 트랙 안에서만 스크롤(콘텐츠로 인해 트랙이 늘어나 페이지 전체가 스크롤되지 않도록 min-height:0) */ + min-height: 0; + overflow-y: auto; + overflow-x: hidden; /* 페이지 가로 스크롤 방지 — 넓은 표/차트는 각자 컨테이너에서 스크롤 */ + -webkit-overflow-scrolling: touch; } .layout-bottom { @@ -466,7 +471,6 @@ watch(() => route.fullPath, () => ui.closeSidebar()) } .layout-body { padding: 1rem; - padding-bottom: calc(56px + env(safe-area-inset-bottom, 0) + 1rem); } }