frontend/css

10. 📍 CSS Position 완벽 가이드 — relative, absolute, fixed, sticky 총정리

mirabo01 2025. 11. 5. 21:05

Flex, Grid까지 배웠다면 이제 요소의 “정확한 위치”를 컨트롤하는 기술이 필요하다.
바로 그 역할을 하는 게 position 이다.

버튼을 오른쪽 아래에 고정시키고 싶다거나,
배지 뱃지를 아이콘 오른쪽 위에 살짝 띄우고 싶거나,
스크롤해도 계속 붙어 있는 헤더를 만들고 싶다면
position: relative / absolute / fixed / sticky 를 이해해야 한다.

이번 글에서 이 네 가지를 한 번에 정리해보자.


💡 1. position이 하는 일 한 줄 정리

“position은 요소를 어디를 기준으로 어떻게 배치할지 결정하는 속성이다.”

기본값은 static이고, 나머지가 우리가 흔히 쓰는 네 가지다.

position: static;   /* 기본값 */ 
position: relative; 
position: absolute; 
position: fixed; 
position: sticky; 

이때 함께 따라다니는 속성이 바로 👇
top, right, bottom, left, z-index 이다.

.box { 
  position: absolute; 
  top: 10px; 
  right: 20px; 
} 

🧱 2. 기본값 static — “아무것도 안 한 상태”

.box { 
  position: static; /* 안 써도 기본값 */ 
} 
  • HTML 문서 흐름(정상 흐름, normal flow)에 맞게 배치
  • top, left 같은 속성을 써도 아무 효과 없음
  • 대부분의 요소는 기본적으로 이 상태

사실상 “포지션 안 건드렸을 때 상태”라고 보면 된다.


📌 3. relative — “제자리에서 살짝 움직이기 + 기준점 만들기”

.box { 
  position: relative; 
  top: 10px; 
  left: 20px; 
} 

특징 두 가지가 중요하다:

  1. 원래 위치를 기준으로 살짝 이동
    • top: 10px → 아래로 10px
    • left: 20px → 오른쪽으로 20px
    • 원래 있던 자리의 “공간”은 그대로 차지한 상태에서 화면만 이동
  2. 자식 absolute의 기준점이 되어줌 (진짜 핵심)
<div class="wrap"> 
  <div class="badge">NEW</div> 
</div> 
.wrap { 
  position: relative; 
  width: 100px; 
  height: 100px; 
  background: #eee; 
} 
 
.badge { 
  position: absolute; 
  top: -5px; 
  right: -5px; 
  background: crimson; 
  color: #fff; 
  padding: 4px 8px; 
  border-radius: 999px; 
  font-size: 12px; 
} 

.wrap에 position: relative 가 있기 때문에
.badge는 브라우저 전체가 아니라 wrap 박스를 기준으로 배치된다.

👉 실무에서 relative는 “기준점용”으로 거의 항상 같이 쓰인다.


🎯 4. absolute — “부모를 기준으로 완전히 떼어내기”

.badge { 
  position: absolute; 
  top: 0; 
  right: 0; 
} 

특징 정리:

  • 문서의 일반 흐름(normal flow) 밖으로 나감 (위치 차지 X)
  • 가장 가까운 position이 설정된 조상 요소를 기준으로 배치
    • 없으면 body(뷰포트)를 기준으로 배치
  • top, left, right, bottom 값으로 정확한 위치 지정

그래서 대부분 이렇게 쓴다 👇

.parent { 
  position: relative;  /* 기준 */ 
} 
 
.child { 
  position: absolute;  /* 기준에 붙이기 */ 
  top: 0; 
  right: 0; 
} 

💡 정리하자면

absolute는 “조상 중에서 포지션이 설정된 애”를 기준으로 붙는다.


📌 5. fixed — “스크롤해도 항상 화면에 고정”

.chat-button { 
  position: fixed; 
  right: 20px; 
  bottom: 20px; 
} 

특징:

  • 기준: 브라우저 화면(뷰포트) 자체
  • 스크롤을 하더라도 항상 같은 자리에 있음
    → 채팅 버튼, “맨 위로 가기” 버튼, 고정 네비게이션 등에 사용

예시:

<button class="top-btn">⬆ 맨 위로</button> 
.top-btn { 
  position: fixed; 
  right: 24px; 
  bottom: 24px; 
  padding: 10px 14px; 
  border-radius: 50px; 
  border: none; 
  background: royalblue; 
  color: #fff; 
  cursor: pointer; 
} 

이러면 어느 위치에서나 항상 화면 오른쪽 아래에 버튼이 보인다.


🧲 6. sticky — “원래는 흐르다가, 특정 지점부터 고정”

sticky는 relative와 fixed의 혼합 느낌이다.

.header { 
  position: sticky; 
  top: 0; 
} 

특징:

  • 처음에는 일반 요소처럼 스크롤에 따라 위로 올라감 (relative처럼 행동)
  • 지정한 top(또는 bottom) 위치에 도달하면 그때부터 고정 (fixed처럼 행동)
  • 부모 영역을 벗어나면 고정도 풀림 → 부모 높이 영향을 받는다

예시: 스크롤하면 상단에 붙는 헤더

<header class="header">상단 메뉴</header> 
<section>길~~게 내용...</section> 
.header { 
  position: sticky; 
  top: 0; 
  background: #111; 
  color: #fff; 
  padding: 12px 20px; 
  z-index: 10; 
} 

💡 주의점:

  • sticky가 먹으려면 부모 height가 충분히 길어야
  • overflow: hidden / auto 설정이 부모에 있으면 sticky가 예상대로 안 먹을 때가 있다

🧮 7. top / left / right / bottom 의 기준 정리

position 기준이 되는 곳

static 무시됨 (적용 X)
relative 자기 원래 자리 (자기 자신 기준 살짝 이동)
absolute 가장 가까운 position 지정 조상 (없으면 body)
fixed 브라우저 화면(뷰포트)
sticky 스크롤 영역 + 지정한 top/bottom 위치

이 네 가지 기준만 머리에 들어오면
“왜 여기서 이렇게 움직이지?” 하는 의문이 대부분 해결된다.


🎨 8. z-index — 위아래 순서 정하기

position이 걸려있는 요소들끼리는 위/아래 순서도 중요하다.
이걸 정하는 게 z-index 다.

.box1 { 
  position: relative; 
  z-index: 10; 
} 
.box2 { 
  position: relative; 
  z-index: 5; 
} 
  • 숫자가 클수록 위에 쌓임
  • position이 없는(static) 요소에는 z-index가 의미 없음
  • 너무 높은 값 남발하면 나중에 관리 지옥 → 작은 숫자 위주로 설계

🧩 9. 실무에서 자주 쓰는 패턴 3가지

1) 아이콘 오른쪽 위에 뱃지 붙이기

<div class="icon-wrap"> 
  <img src="bell.svg" class="icon" /> 
  <span class="badge">3</span> 
</div> 
.icon-wrap { 
  position: relative; 
  display: inline-block; 
} 
 
.badge { 
  position: absolute; 
  top: -4px; 
  right: -4px; 
  background: crimson; 
  color: #fff; 
  border-radius: 999px; 
  padding: 2px 6px; 
  font-size: 11px; 
} 

2) 전체를 덮는 모달 배경

<div class="overlay"> 
  <div class="modal">내용</div> 
</div> 
.overlay { 
  position: fixed; 
  inset: 0; /* top:0; right:0; bottom:0; left:0; 와 같음 */ 
  background: rgba(0,0,0,0.5); 
  display: flex; 
  justify-content: center; 
  align-items: center; 
  z-index: 100; 
} 
 
.modal { 
  background: #fff; 
  padding: 20px; 
  border-radius: 12px; 
  min-width: 280px; 
} 

3) 오른쪽 아래 고정 채팅 버튼

<button class="chat-btn">💬</button> 
.chat-btn { 
  position: fixed; 
  right: 20px; 
  bottom: 20px; 
  width: 56px; 
  height: 56px; 
  border-radius: 50%; 
  border: none; 
  background: #4f46e5; 
  color: #fff; 
  font-size: 22px; 
  cursor: pointer; 
  box-shadow: 0 8px 18px rgba(0,0,0,0.25); 
} 

⚠️ 10. position 쓸 때 자주 하는 실수들

  1. absolute만 쓰고 relative 안 씀
    • → 기준이 body가 되어 레이아웃이 이상하게 튐
  2. fixed 요소가 다른 요소를 가려버림
    • → z-index와 padding-top / margin-top 조정 필요
  3. sticky가 안 먹는다고 느껴질 때
    • 부모 요소에 overflow 설정이 있는지, height가 충분한지 확인
  4. position으로 모든 걸 해결하려고 함
    • 레이아웃은 Flex & Grid로,
    • position은 “특수한 위치 조정용”으로 쓰는 게 훨씬 안정적

🏁 11. 마무리 — “position은 레이아웃이 아니라, 레이아웃의 예외를 위한 도구”

레이아웃의 큰 틀은 Flex / Grid가 담당하고,
position은 그중에서 특별히 띄워야 하는 요소들을 다룰 때 빛을 발한다.

  • relative: 기준점 + 살짝 이동
  • absolute: 기준에 딱 붙이기
  • fixed: 화면에 고정
  • sticky: 스크롤하다가 고정

이 네 가지 패턴만 정확히 이해하면
실무에서 마주치는 대부분의 “정렬·위치 문제”를 훨씬 편하게 해결할 수 있다.

“레이아웃은 Flex/Grid로,
포지셔닝은 position으로.”