Learning
레슨 9 / 13·7개 토픽

CSS 포지셔닝과 z-index

position 속성 이해하기

CSS position 속성은 요소가 문서 내에서 어떻게 배치될지 결정합니다. 기본값인 static부터 relative, absolute, fixed, sticky까지 5가지 값이 있으며, 각각의 동작 방식이 다릅니다. 포지셔닝을 제대로 이해하면 복잡한 레이아웃도 자유자재로 구현할 수 있습니다.

position: static (기본값)

static은 모든 요소의 기본 포지션입니다. 문서의 일반적인 흐름(Normal Flow)에 따라 배치되며, top, right, bottom, left, z-index 속성이 적용되지 않습니다.

css
/* static: 일반 흐름에 따라 배치 (기본값) */
.box {
  position: static;
  /* top, left 등을 지정해도 무시됩니다 */
  top: 50px;  /* 적용되지 않음 */
}

position: relative

relative는 요소를 원래 위치 기준으로 상대적으로 이동시킵니다. 요소가 차지하던 원래 공간은 유지되므로 주변 요소의 레이아웃에 영향을 주지 않습니다. absolute 자식의 기준점으로도 자주 사용됩니다.

css
/* relative: 원래 위치에서 상대 이동 */
.box {
  position: relative;
  top: 20px;    /* 원래 위치에서 아래로 20px */
  left: 10px;   /* 원래 위치에서 오른쪽으로 10px */
}

/* 자식 absolute의 기준점으로 사용 */
.parent {
  position: relative;  /* 기준점 설정 */
}
.child {
  position: absolute;  /* parent 기준으로 배치 */
  top: 0;
  right: 0;
}

position: absolute

absolute는 요소를 일반 흐름에서 제거하고, 가장 가까운 positionstatic이 아닌 조상 요소를 기준으로 배치합니다. 기준 조상이 없으면 을 기준으로 합니다. 모달, 드롭다운 메뉴, 툴팁 등에 널리 사용됩니다.

css
/* absolute: 가장 가까운 positioned 조상 기준 */
.tooltip-wrapper {
  position: relative;  /* 기준점 */
}

.tooltip {
  position: absolute;
  bottom: 100%;        /* 부모 위에 배치 */
  left: 50%;
  transform: translateX(-50%);  /* 수평 중앙 정렬 */
  background: #333;
  color: #fff;
  padding: 8px 12px;
  border-radius: 4px;
  white-space: nowrap;
}

position: fixed

fixed는 요소를 뷰포트(브라우저 화면)를 기준으로 고정합니다. 스크롤해도 화면의 같은 위치에 머무릅니다. 고정 헤더, 플로팅 버튼, 쿠키 동의 배너 등에 사용됩니다.

css
/* fixed: 뷰포트 기준 고정 */
.fixed-header {
  position: fixed;
  top: 0;
  left: 0;
  width: 100%;
  background: #fff;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
  z-index: 1000;
}

/* 고정 헤더 높이만큼 body에 여백 추가 */
body {
  padding-top: 64px;
}

/* 하단 플로팅 버튼 */
.fab {
  position: fixed;
  bottom: 24px;
  right: 24px;
  width: 56px;
  height: 56px;
  border-radius: 50%;
  background: #10b981;
  z-index: 900;
}

position: sticky

stickyrelativefixed의 하이브리드입니다. 평소에는 일반 흐름에 따르다가, 스크롤이 지정된 임계점(예: top: 0)에 도달하면 fixed처럼 고정됩니다. 스크롤 가능한 부모의 범위 안에서만 동작합니다.

css
/* sticky: 스크롤 시 고정되는 요소 */
.sticky-nav {
  position: sticky;
  top: 0;              /* 뷰포트 상단에 닿으면 고정 */
  background: #fff;
  z-index: 100;
  border-bottom: 1px solid #e5e7eb;
}

/* 테이블 헤더를 sticky로 */
.data-table thead th {
  position: sticky;
  top: 0;
  background: #f9fafb;
}

/* 사이드바 목차 */
.toc {
  position: sticky;
  top: 80px;  /* 헤더 아래에 고정 */
  max-height: calc(100vh - 100px);
  overflow-y: auto;
}

z-index와 쌓임 맥락

z-index는 요소의 쌓임 순서(앞뒤 겹침)를 제어합니다. 값이 클수록 앞에 표시됩니다. 단, positionstatic이 아닌 요소에만 적용됩니다. 새로운 쌓임 맥락(Stacking Context)은 z-index가 지정된 positioned 요소, opacity < 1, transform, filter 등에서 생성됩니다.

css
/* z-index 체계를 변수로 관리하면 충돌을 방지할 수 있습니다 */
:root {
  --z-dropdown: 100;
  --z-sticky:   200;
  --z-overlay:  300;
  --z-modal:    400;
  --z-toast:    500;
}

/* 모달 오버레이 예시 */
.overlay {
  position: fixed;
  inset: 0;
  background: rgba(0, 0, 0, 0.5);
  z-index: var(--z-overlay);
}

.modal {
  position: fixed;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  z-index: var(--z-modal);
  background: #fff;
  border-radius: 12px;
  padding: 32px;
}
💡

z-index는 같은 쌓임 맥락 안에서만 비교됩니다. 부모 요소가 새 쌓임 맥락을 만들면 자식의 z-index: 9999도 부모 밖의 요소와 비교되지 않습니다. 디버깅이 어려울 때는 브라우저 개발자 도구에서 "3D View"를 활용해 쌓임 순서를 시각적으로 확인하세요.