position: sticky는 하이브리드입니다: 요소가 지정한 임계점까지 스크롤될 때까지 relative처럼 동작하다가(정상 흐름에 머무름), 이후 fixed처럼 동작합니다(제자리에 고정) — 하지만 **포함 블록(containing block)**이 아직 화면에 있는 동안에만.
{
: sticky;
: ;
}
top(또는 bottom/left/right) 값은 필수입니다 — 임계점을 정의합니다. 그것이 없으면 sticky는 아무것도 하지 않습니다.
sticky 요소는 부모 컨테이너에 한정됩니다. 그 부모를 통과해 스크롤하는 동안 고정되다가, 부모의 하단이 지나가면 함께 스크롤되어 사라집니다. 이것이 "sticky 섹션 헤더"가 작동하는 방식입니다 — 각 헤더는 자신의 섹션이 화면에 있는 동안에만 고정됩니다.
1. 조상에 overflow: hidden/auto/scroll이 있음. 이것이 1번 원인입니다. sticky 위치 지정은 스크롤 가능한 조상에 의해 깨지는데, 요소가 페이지가 아니라 그 스크롤 컨테이너 기준으로 고정되기 때문입니다.
.wrapper { overflow: hidden; } /* ❌ 자손의 sticky를 조용히 죽임 */
2. 부모가 충분히 높지 않음. sticky는 부모가 sticky 요소보다 높아야만 고정될 공간이 있습니다 — 부모가 같은 높이면 통과해 스크롤할 것이 없어 절대 고정된 것처럼 보이지 않습니다.
3. 임계점 미설정. top/bottom을 잊으면 고정 지점이 없습니다.
4. 부모의 높이 제약(예: 아이템을 늘리는 flex 부모)도 스크롤 공간을 제거할 수 있습니다.
✓ top/bottom/left/right를 설정했는가?
✓ 어떤 조상이라도 visible이 아닌 overflow를 가지고 있는가?
✓ 부모 컨테이너가 sticky 요소보다 높은가?
position: sticky는 JavaScript 없이 sticky 헤더, 테이블 헤더, 사이드바, "scrollspy" UI를 구동합니다.
하지만 그 특이점들 — 특히 어떤 조상의 overflow라도 조용히 깨뜨린다는 점 — 때문에 "왜 이게 고정이 안 되지?" 디버깅의 잦은 원인이 됩니다.
포함 블록 범위와 overflow 함정을 아는 것이 이를 안정적으로 사용하게 해줍니다.
주니어부터 시니어까지 상세한 답변이 포함된 IT 면접 질문 라이브러리.
후원하기