position: sticky를 넣었는데 아무 일도 일어나지 않은 이유
문제 발생
사이드바 제목을 스크롤에 따라 붙여 두려고 position: sticky를 줬는데, 에러도 경고도 없이 그냥 평범하게 스크롤됐습니다.
.sidebar { overflow-x: auto; } /* 가로 스크롤용으로 넣어둔 것 */
.sidebar h2 { position: sticky; top: 0; }원인 분석
sticky가 동작하지 않는 이유는 대부분 셋 중 하나이고, 셋 다 아무 오류도 내지 않습니다.
1. 조상의 overflow가 visible이 아님. 이게 가장 흔합니다. 조상 중 하나라도 overflow가 hidden, scroll, auto면 그 요소가 스크롤 컨테이너가 되고, sticky 요소는 그 안에서 기준을 잡으려 합니다. 그런데 그 컨테이너가 스크롤되지 않으면 붙을 일도 없습니다. 위 코드의 overflow-x: auto가 정확히 이 경우입니다 — 가로 스크롤만 원했는데 세로 축까지 함께 영향을 받습니다.
2. 임계값을 주지 않음. top, bottom, left, right 중 최소 하나가 auto가 아니어야 합니다. position: sticky만 쓰면 "어디에 붙을지"를 모르므로 아무것도 하지 않습니다.
3. 부모의 높이가 sticky 요소와 같음. sticky는 부모 박스 안에서만 움직입니다. 부모가 자식 높이만큼만 차지하면 움직일 공간이 0이라 붙어 있을 구간이 없습니다.
해결 방안
- 조상의 overflow를 확인합니다. 한 줄로 훑을 수 있습니다.
let el = document.querySelector(".sidebar h2");
while ((el = el.parentElement)) {
const o = getComputedStyle(el).overflow;
if (o !== "visible") console.log("스크롤 컨테이너:", el, o);
}- 가로 스크롤만 필요하면 축을 명시합니다.
overflow-x: auto는 세로 축을auto로 만들지 않지만, 계산된 값이visible이 아니게 되는 경우가 있습니다. 세로를 명시적으로 열어 둡니다.
.sidebar { overflow-x: auto; overflow-y: visible; }- 임계값을 반드시 줍니다. 헤더가 있다면 그 높이만큼 띄웁니다.
.sidebar h2 { position: sticky; top: var(--header-height); }- 부모에게 움직일 공간이 있는지 봅니다. 표의
<thead>를 붙일 때처럼, sticky 요소가 놓인 부모가 뷰포트보다 길어야 붙는 구간이 생깁니다. - 다른 sticky 요소와 겹치면 순서를 정합니다. 헤더와 그 아래 탭 바를 같이 붙일 때는 각자의
top을 앞선 요소의 높이만큼 더해 줘야 합니다 — 이 프로젝트의 배우기 화면이 그렇게 쌓여 있습니다.
댓글0
댓글을 남기려면 로그인이 필요해요. 로그인
아직 댓글이 없어요. 첫 의견을 편하게 남겨 보세요.