스크롤 위치가 원하는 곳으로 가지 않고 꼬인다면? - scroll-margin-top
작성일: 2026년 3월 15일 오후 05:15(마지막 수정: 2026년 3월 27일 오후 07:05)
조회수: 22
[React] 토글 접을 때 스크롤 위치가 꼬인다면? (feat. CSS의 마법)
리액트에서 긴 컨텐츠를 토글(Toggle)로 만들 때, 하단 버튼을 눌러 컨텐츠를 접으면서 다시 위로 스크롤 시키는 기능을 구현하다 보면 예상치 못한 난관에 부딪히곤 합니다. 분명 scrollIntoView를 썼는데 왜 헤더가 잘리거나 위치가 이상할까요?
1. 범인은 '레이아웃의 변화'와 '오프셋'
보통 상단에 고정된(Sticky/Fixed) 메뉴가 있는 경우, scrollIntoView는 요소의 최상단을 브라우저의 최상단(0,0)에 맞추려 합니다. 결과적으로 내 소중한 타이틀이 고정 헤더 뒤로 숨어버리는 현상이 발생하죠.

헤더 저 밑 어딘가에 뭔가 있다..
2. 해결사: scroll-margin-top
CSS 한 줄이면 해결됩니다.
css/* 이동하고 싶은 목적지 요소에 추가 */ .toggle-header { /* 상단 고정 헤더의 높이 + 여유 공간만큼 설정 */ scroll-margin-top: 80px; }
jsx// tailwindcss의 경우 <div ref={targetRef} className={"scroll-m-16"} > ... </div>
이 속성은 브라우저에게 이렇게 말하는 것과 같습니다: "야, 이 요소로 스크롤 할 때 위에 80px 정도는 여유 좀 줘!"
이를 통해 레이아웃 자체에 영향을 주는 Margin을 사용할 방법을 고려하거나, 복잡하게 좌표를 계산하여 직접 스크롤(window.scrollTo({ top: ... }))할 필요 없습니다.
3. 전체 흐름도
토글이 닫히면서 스크롤이 이동하는 과정을 시각화하면 다음과 같습니다.
mermaid
4. 최종 코드 스니펫(예시)
CSS
css.accordion-header { scroll-margin-top: 100px; /* 고정 헤더보다 조금 더 여유 있게 */ transition: all 0.3s; }
React Component
jsxconst handleCollapse = () => { // 1. 상태 변경 (컨텐츠 접기) setIsExpanded(false); // 2. 스크롤 이동 (CSS가 위치를 보정해줌) headerRef.current?.scrollIntoView({ behavior: "smooth", block: "start", }); };
마치며
스크롤 문제는 JS 문제 같아 보이지만, 의외로 CSS로 해결할 때 가장 깔끔합니다. scroll-margin-top은 브라우저 호환성도 좋으니(IE 제외) 적극 활용해 보세요!
0개의 댓글
💬
아직 댓글이 없습니다
첫 번째 댓글을 작성해보세요!