이번 편의 결과물: 페이지를 스크롤해도 헤더가 화면 상단에 계속 보입니다. · 다루는 개념: position의 5가지 값, sticky의 동작 조건, 최소한의 z-index
이 편에서 만드는 파일
web-practice/portfolio/
└ css/
└ styles.css ~ (.site-header에 position: sticky 추가)개념 정리
position 속성은 요소를 문서의 기본 흐름에서 어떻게 빼낼지 결정합니다.
| 값 | 동작 |
|---|---|
static (기본값) | 문서 흐름을 그대로 따른다. top/left 등이 적용되지 않는다 |
relative | 흐름은 그대로 차지하되, 원래 자리를 기준으로 top/left만큼 시각적으로 이동한다 |
absolute | 흐름에서 완전히 빠져나와 가장 가까운 relative/absolute/fixed 조상(containing block) 기준으로 위치를 잡는다 |
fixed | 뷰포트(화면) 기준으로 고정되어 스크롤해도 움직이지 않는다 |
sticky | 평소엔 relative처럼 흐름을 따르다가, 지정한 임계값(top 등)에 닿으면 fixed처럼 고정된다 |
지금 헤더는 position을 지정하지 않아 기본값 static입니다. 페이지를 스크롤하면 헤더도 본문과 함께 위로 밀려 사라집니다. sticky로 바꾸면 스크롤이 헤더의 원래 위치를 지날 때까지는 relative처럼 흐르다가, 그 지점부터는 top: 0에 붙어 고정됩니다.
sticky가 작동하려면 두 조건이 필요합니다.
top(또는bottom/left/right) 중 최소 하나에 구체적인 값을 지정해야 합니다. 값이 없으면 언제 고정할지 브라우저가 판단할 기준이 없습니다.- 조상 요소 중 어느 하나라도
overflow: hidden(또는auto/scroll)이 걸려 있으면 그 조상 안에서만 sticky가 작동하거나, 아예 동작을 멈춥니다.
헤더가 고정된 뒤에는 본문 콘텐츠가 스크롤을 통해 헤더 위로 올라올 수 있습니다. 헤더가 항상 맨 위에 보이도록 z-index로 쌓임 순서를 지정합니다. z-index는 값이 클수록 위에 쌓이며, 지금은 헤더 하나만 고려하므로 작은 양수(예: 10) 정도면 충분합니다.
자주 하는 오해: sticky를 fixed와 혼동하기 쉽지만, fixed는 처음부터 항상 화면에 고정되어 스크롤 위치와 무관하게 같은 자리에 있습니다. 반면 sticky는 원래 자리를 지나야 고정되기 시작합니다. 지금 헤더는 페이지 맨 위에 있으므로 두 값의 차이가 잘 안 보이지만, 페이지 중간에 있는 요소라면 확실히 다르게 동작합니다.
실습
1. 지금 상태 확인하기
index.html을 브라우저에서 열고 아래로 스크롤합니다. 헤더가 본문과 함께 위로 사라지는 것을 확인합니다(position이 static이기 때문입니다).
2. css/styles.css의 .site-header에 sticky 추가하기
09편에서 만든 .site-header 규칙에 아래 세 줄을 추가합니다.
/* css/styles.css (.site-header 규칙에 추가) */
.site-header {
display: flex;
align-items: center;
flex-wrap: wrap;
padding: var(--space-4) var(--space-6);
height: var(--header-height);
position: sticky;
top: 0;
z-index: 10;
background: var(--color-bg);
border-bottom: 1px solid var(--color-border);
}background와 border-bottom을 함께 넣는 이유는, 헤더가 고정된 상태에서 아래 콘텐츠가 스크롤되어 헤더 뒤로 지나갈 때 배경이 없으면 글자가 겹쳐 보이기 때문입니다.
3. 실행
파일을 저장하고 index.html을 새로고침합니다.
4. 확인
- 페이지를 아래로 스크롤해도 헤더가 화면 맨 위에 계속 보입니다.
- 헤더 아래로 지나가는 본문 텍스트가 헤더 뒤에 비치지 않고 헤더 배경에 가려집니다.
projects.html·contact.html에서도 같은 결과가 나옵니다(같은css/styles.css를 공유하기 때문).
직접 해보기
top: 0을 지워 보고 헤더가 더 이상 고정되지 않는지 확인한 뒤 되돌립니다.position: sticky를position: fixed로 잠깐 바꿔 봅니다. 헤더는 여전히 고정되지만 본문 맨 위 내용이 헤더 뒤에 가려 시작되는 문제가 생기는지 확인하고, 그 이유(fixed는 흐름에서 완전히 빠져 본문이 그 자리를 대신 차지하기 때문)를 이해한 뒤sticky로 되돌립니다.
답 보기
top 없이 position: sticky만 있으면 브라우저가 언제 고정할지 판단할 기준이 없어 static과 똑같이 동작합니다.
position: fixed로 바꾸면 헤더가 문서 흐름에서 빠져나가므로, 헤더가 있던 자리를 본문의 첫 섹션이 대신 차지해 히어로 제목 윗부분이 헤더에 가려집니다. sticky는 흐름을 유지하다 필요할 때만 고정되므로 이런 문제가 없습니다.
자주 하는 실수
| 증상 | 원인 | 고치는 법 |
|---|---|---|
| sticky를 줘도 스크롤하면 그냥 사라진다 | top 값을 지정하지 않음 | top: 0 확인 |
| 헤더는 고정되는데 본문 텍스트가 비쳐 보인다 | background를 지정하지 않음 | .site-header에 불투명한 background 추가 |
| 헤더가 다른 요소 아래에 깔린다 | z-index를 지정하지 않아 쌓임 순서가 뒤짐 | z-index에 다른 요소보다 큰 값을 지정 |
| body 맨 위 내용이 헤더에 가려진다 | sticky 대신 fixed를 씀 | 흐름을 유지하는 sticky로 변경 |