CSS에서 position 속성(static, relative, absolute, fixed, sticky)을 설명해주세요.
힌트
각 포지션이 참조하는 기준점(containing block)의 차이를 생각해보세요.
정답 및 해설
CSS에서 position 속성(static, relative, absolute, fixed, sticky)을 설명해주세요.
CSS position 속성은 요소가 문서 내에서 어떻게 배치되는지를 결정합니다. 기본 문서 흐름(normal flow)을 따를지, 특정 기준점을 기준으로 위치를 지정할지를 제어합니다. top, right, bottom, left 속성과 함께 사용하여 정확한 위치를 지정합니다.
static (기본값)
모든 요소의 기본 position 값입니다. 일반 문서 흐름을 그대로 따르며, top, right, bottom, left, z-index 속성이 적용되지 않습니다.
.element {
position: static; /* 기본값이므로 명시할 필요 없음 */
}
명시적으로 static을 선언하는 경우는 다른 position 값을 재설정할 때 사용합니다.
relative
자신의 원래 위치(static일 때의 위치)를 기준으로 top, right, bottom, left 값만큼 이동합니다. 중요한 점은, 이동하더라도 원래 공간은 그대로 유지된다는 것입니다. 주변 요소들은 해당 요소가 이동하지 않은 것처럼 배치됩니다.
.box {
position: relative;
top: 20px; /* 원래 위치보다 20px 아래로 */
left: 30px; /* 원래 위치보다 30px 오른쪽으로 */
}
<div class="container">
<div class="box-a">A</div>
<div class="box-b" style="position: relative; top: 20px;">B</div>
<!-- B가 아래로 20px 내려가도, A와 C 사이의 공간은 유지됨 -->
<div class="box-c">C</div>
</div>
relative의 핵심 역할: positioned 조상 생성
position: relative의 가장 중요한 활용은 absolute를 사용할 자식 요소의 기준점(containing block) 이 되는 것입니다.
.card {
position: relative; /* absolute 자식의 기준점이 됨 */
width: 300px;
height: 200px;
}
.badge {
position: absolute;
top: 8px;
right: 8px; /* .card 기준으로 우상단에 배치 */
}
absolute
가장 가까운 positioned 조상 요소(position이 static이 아닌 요소)를 기준으로 배치됩니다. positioned 조상이 없으면 초기 컨테이닝 블록(보통 <html> 또는 뷰포트)을 기준으로 합니다. 문서 흐름에서 완전히 제거되므로, 다른 요소들이 해당 공간을 무시하고 배치됩니다.
.parent {
position: relative; /* absolute 자식의 기준점 */
width: 400px;
height: 300px;
background: #f0f0f0;
}
.child {
position: absolute;
bottom: 16px;
right: 16px; /* .parent의 우하단 기준 16px 안쪽 */
width: 100px;
height: 40px;
}
실제 활용 패턴
/* 툴팁 */
.tooltip-wrapper {
position: relative;
display: inline-block;
}
.tooltip {
position: absolute;
bottom: 100%; /* 부모 위에 배치 */
left: 50%;
transform: translateX(-50%);
white-space: nowrap;
background: #333;
color: white;
padding: 4px 8px;
border-radius: 4px;
}
/* 이미지 위 오버레이 */
.image-container {
position: relative;
}
.overlay {
position: absolute;
inset: 0; /* top: 0; right: 0; bottom: 0; left: 0; 의 단축 */
background: rgba(0, 0, 0, 0.5);
display: flex;
align-items: center;
justify-content: center;
}
fixed
뷰포트(viewport)를 기준으로 배치됩니다. 페이지를 스크롤해도 항상 같은 위치에 고정됩니다. absolute와 마찬가지로 문서 흐름에서 제거됩니다.
/* 화면 상단에 고정된 네비게이션 */
.navbar {
position: fixed;
top: 0;
left: 0;
right: 0;
height: 60px;
background: white;
z-index: 1000;
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
}
/* fixed 네비게이션이 콘텐츠를 가리지 않도록 여백 추가 */
body {
padding-top: 60px;
}
/* 우하단 플로팅 버튼 */
.fab {
position: fixed;
bottom: 24px;
right: 24px;
width: 56px;
height: 56px;
border-radius: 50%;
background: #1976d2;
color: white;
z-index: 100;
}
/* 쿠키 배너 */
.cookie-banner {
position: fixed;
bottom: 0;
left: 0;
right: 0;
padding: 16px;
background: #333;
color: white;
}
fixed 주의사항: transform 부모 문제
부모 요소에 transform, perspective, filter 속성이 적용되어 있으면, position: fixed가 뷰포트 대신 해당 부모를 기준으로 동작하는 예외가 있습니다.
/* 이 경우 .modal 내부의 fixed 요소는 뷰포트 기준이 아닌 .modal 기준 */
.modal {
transform: translateX(0); /* transform이 새로운 stacking context 생성 */
}
sticky
스크롤 위치에 따라 relative와 fixed 사이를 전환합니다. 지정한 임계값에 도달하기 전에는 relative처럼 동작하고, 임계값에 도달하면 fixed처럼 고정됩니다. 스크롤을 내려 해당 요소의 부모 컨테이너를 벗어나면 다시 흐름에 따라 이동합니다.
/* 스크롤 시 상단에 고정되는 섹션 헤더 */
.section-header {
position: sticky;
top: 0; /* 뷰포트 상단에서 0px가 되면 고정 시작 */
background: white;
z-index: 10;
padding: 12px 0;
border-bottom: 1px solid #eee;
}
/* 사이드바 목차 (스크롤해도 보임) */
.toc {
position: sticky;
top: 80px; /* 네비게이션(60px) 아래에서 고정 */
max-height: calc(100vh - 80px);
overflow-y: auto;
}
/* 테이블 헤더 고정 */
th {
position: sticky;
top: 0;
background: #f5f5f5;
z-index: 1;
}
sticky가 작동하지 않는 경우
/* 부모에 overflow: hidden/auto/scroll이 설정되어 있으면 sticky가 작동 안 함 */
.parent {
overflow: hidden; /* sticky 자식이 작동하지 않음 */
}
/* 해결: overflow를 제거하거나 visible로 변경 */
.parent {
overflow: visible;
}
5가지 position 속성 종합 비교
| 속성 | 기준점 | 문서 흐름 | 스크롤 시 | 주요 용도 |
|---|---|---|---|---|
| static | 없음 | 유지 | 함께 이동 | 기본 배치 |
| relative | 자기 자신의 원래 위치 | 유지 | 함께 이동 | 미세 조정, absolute 기준 생성 |
| absolute | 가장 가까운 positioned 조상 | 제거 | 조상과 함께 이동 | 팝업, 툴팁, 배지, 오버레이 |
| fixed | 뷰포트 | 제거 | 고정 | 네비게이션, FAB, 쿠키 배너 |
| sticky | 스크롤 컨테이너 | 유지 | 임계값까지 이동 후 고정 | 섹션 헤더, 사이드바 TOC |
z-index와 쌓임 맥락(Stacking Context)
position이 static이 아닌 요소는 z-index를 통해 쌓임 순서를 제어할 수 있습니다.
.modal-backdrop {
position: fixed;
inset: 0;
background: rgba(0, 0, 0, 0.5);
z-index: 100; /* 일반 콘텐츠 위 */
}
.modal {
position: fixed;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
z-index: 101; /* backdrop 위 */
}
.tooltip {
position: absolute;
z-index: 200; /* 모달보다 위 */
}
z-index는 같은 쌓임 맥락 내에서만 비교됩니다. 부모가 새로운 쌓임 맥락을 생성하면 자식의 z-index는 해당 맥락 내에서만 유효합니다.
정리
position 속성 선택의 가이드라인은 다음과 같습니다.
- 특별한 배치가 필요 없으면 →
static(기본값) - 약간 위치를 조정하거나
absolute기준을 만들려면 →relative - 특정 부모를 기준으로 띄워서 배치하려면 →
absolute - 스크롤에 관계없이 항상 화면 같은 위치에 →
fixed - 스크롤하다가 특정 지점에서 고정되게 하려면 →
sticky