position

요소가 문서 내에서 어떻게 배치되는지를 결정하는 속성입니다. top, right, bottom, left, z-index와 함께 사용합니다.

클래스 목록

클래스CSS설명
pstposition: static기본값. 문서 흐름에 따라 배치. top/left 등 무시
prposition: relative원래 위치 기준 오프셋. 자식 absolute의 기준점
paposition: absolute흐름에서 제거. 가장 가까운 positioned 부모 기준 배치
pfposition: fixed뷰포트 기준 고정. 스크롤해도 위치 유지
psposition: stickyrelative + fixed 하이브리드. 스크롤 임계점에서 고정
piposition: initial초기값(static)으로 리셋

시각적 비교

각 position 값이 요소에 어떤 영향을 주는지 비교합니다.

Static (기본값) — pst

static 요소

문서 흐름에 따라 배치됩니다. top/left 등이 무시됩니다.

Relative — pr

원래 위치 (점선)
pr t2rem l2rem

원래 위치에서 top: 2rem, left: 2rem만큼 이동합니다. 원래 공간은 유지됩니다.

Absolute — pa

부모 (pr)
pa t8px r8px
pa b8px l8px

문서 흐름에서 제거, 부모 기준 배치

Fixed — pf

pf 시뮬레이션

실제 pf는 뷰포트에 고정됩니다. 스크롤해도 위치가 변하지 않습니다.

Sticky — ps

스크롤 콘텐츠 1
ps t0 (스크롤하면 상단에 고정)
스크롤 콘텐츠 2
스크롤 콘텐츠 3
스크롤 콘텐츠 4

위 박스를 스크롤하면 보라색 요소가 상단에 고정됩니다.

언제 뭘 쓸까?

상황추천이유
드롭다운 메뉴pa부모 기준으로 정확한 위치에 표시
고정 헤더/네비게이션pf / ps스크롤해도 항상 보이게 고정
툴팁/팝오버pa트리거 요소 기준으로 표시
모달 오버레이pf뷰포트 전체를 덮는 배경
위치 미세 조정pr원래 위치에서 약간의 오프셋
사이드바 고정ps스크롤하다가 특정 위치에서 고정
뱃지/아이콘 오버레이pa부모 위에 겹쳐서 표시

클래스별 상세

pstposition: static

기본값입니다. 요소가 문서의 일반적인 흐름에 따라 배치됩니다. top, right, bottom, left, z-index 속성이 적용되지 않습니다.

<!-- 기본 position (보통 명시할 필요 없음) -->
<div class="pst">
  문서 흐름에 따라 배치됩니다.
  top, left 등이 적용되지 않습니다.
</div>

<!-- 반응형에서 position 리셋 시 사용 -->
<div class="ps sm-pst t0">
  데스크탑: sticky → 모바일: static
</div>

prposition: relative

원래 위치를 기준으로 오프셋을 적용합니다. 원래 공간은 그대로 유지됩니다. 또한 자식 요소의 pa(absolute) 배치 기준점이 됩니다.

<!-- 원래 위치에서 오프셋 -->
<div class="pr t8px l16px">
  원래 위치에서 top: 8px, left: 16px 이동
</div>

<!-- pa 자식의 기준점 역할 (가장 흔한 용도) -->
<div class="pr">
  <img src="avatar.jpg" class="w4-8rem h4-8rem br50p" />
  <span class="pa b0 r0 w12px h12px bg34D399 br50p"></span>
</div>

자주 쓰는 조합

pr zi10기준점 + 쌓임 순서 지정
pr t8px l8px원래 위치에서 미세 조정
pr oh기준점 + 자식 overflow 숨김

paposition: absolute

문서 흐름에서 완전히 제거됩니다. 가장 가까운 positioned 조상(pr, pa, pf)을 기준으로 배치됩니다. positioned 조상이 없으면 뷰포트 기준입니다.

<!-- 부모 기준 우상단 배치 -->
<div class="pr w100p h10rem bg18181B br8px">
  <span class="pa t8px r8px bg6366F1 cFFFFFF py4px px8px br4px fs12px">
    NEW
  </span>
  <div class="p2rem">카드 콘텐츠</div>
</div>

<!-- 드롭다운 메뉴 -->
<div class="pr dib">
  <button class="py8px px16px bg6366F1 cFFFFFF br8px bn cp">메뉴</button>
  <ul class="pa t100p l0 mt4px bg18181B b1pxsolid27272A br8px p16px lsn minw16rem zi10">
    <li class="py4px cFAFAFA">항목 1</li>
    <li class="py4px cFAFAFA">항목 2</li>
    <li class="py4px cFAFAFA">항목 3</li>
  </ul>
</div>

<!-- 가운데 정렬 (transform 조합) -->
<div class="pr h20rem bg18181B br8px">
  <div class="pa t50p l50p neg-tty50p neg-ttx50p bg6366F1 cFFFFFF p2rem br8px">
    정중앙 배치
  </div>
</div>

주의

pa를 사용할 때는 반드시 부모에 pr을 지정하세요. 그렇지 않으면 뷰포트 기준으로 배치되어 예상과 다른 위치에 표시됩니다.

자주 쓰는 조합

pa t0 l0부모 좌상단에 배치
pa t0 r0부모 우상단에 배치
pa b0 r0부모 우하단에 배치
pa t0 l0 r0 b0부모 전체를 덮는 오버레이
pa t100p l0부모 바로 아래에 배치 (드롭다운)
pa t50p l50p가운데 정렬 (transform 필요)

pfposition: fixed

뷰포트를 기준으로 배치됩니다. 스크롤해도 위치가 변하지 않습니다. 고정 헤더, 플로팅 버튼, 모달 오버레이 등에 사용합니다.

<!-- 고정 헤더 -->
<header class="pf t0 l0 r0 bg0F0F17 py12px px2rem zi100 bb1pxsolid27272A">
  <nav class="df jcsb aic">
    <div class="cFAFAFA fw700">Logo</div>
    <div class="df gap2rem">
      <a href="#" class="cA1A1AA tdn">Home</a>
      <a href="#" class="cA1A1AA tdn">About</a>
    </div>
  </nav>
</header>

<!-- 모달 오버레이 -->
<div class="pf t0 l0 w100p h100p bg0-0-0-50 df jcc aic zi999">
  <div class="bg18181B br12px p3-2rem maxw48rem w100p">
    <h2 class="cFAFAFA fs2rem fw700 mb16px">모달 제목</h2>
    <p class="c71717A fs14px">모달 콘텐츠</p>
  </div>
</div>

<!-- 플로팅 버튼 -->
<button class="pf b2rem r2rem w4-8rem h4-8rem br50p bg6366F1 cFFFFFF bn cp zi50 df jcc aic">

</button>

자주 쓰는 조합

pf t0 l0 r0화면 상단 고정 (헤더)
pf b0 l0 r0화면 하단 고정 (푸터/네비)
pf t0 l0 w100p h100p전체 화면 오버레이 (모달 배경)
pf b2rem r2rem우하단 플로팅 버튼
pf t50p l50p뷰포트 중앙 (transform 필요)

psposition: sticky

relative와 fixed의 하이브리드입니다. 스크롤 임계점을 지나면 고정됩니다. 반드시 top 등의 오프셋 값과 함께 사용해야 합니다.

<!-- 스크롤 시 고정되는 네비게이션 -->
<nav class="ps t0 bg0F0F17 py12px px2rem zi50 bb1pxsolid27272A">
  <div class="df gap2rem">
    <a href="#section1" class="cA1A1AA tdn">섹션 1</a>
    <a href="#section2" class="cA1A1AA tdn">섹션 2</a>
    <a href="#section3" class="cA1A1AA tdn">섹션 3</a>
  </div>
</nav>

<!-- 테이블 헤더 고정 -->
<div class="maxh40rem oya">
  <table class="w100p bcc">
    <thead>
      <tr>
        <th class="ps t0 bg18181B py12px px16px zi10">이름</th>
        <th class="ps t0 bg18181B py12px px16px zi10">이메일</th>
      </tr>
    </thead>
    <tbody>
      <!-- 데이터 행들 -->
    </tbody>
  </table>
</div>

<!-- 사이드바 sticky -->
<div class="dg gtc25rem-1fr gap2rem">
  <aside class="ps t2rem ash">
    사이드 네비게이션 (스크롤 시 고정)
  </aside>
  <main>메인 콘텐츠</main>
</div>

주의

ps는 스크롤 컨테이너가 필요합니다. 부모에 oh(overflow: hidden)가 있으면 작동하지 않습니다. 또한 반드시 t0 같은 오프셋 값을 지정해야 합니다.

piposition: initial

position 속성을 초기값(static)으로 되돌립니다. 반응형에서 특정 화면 크기에서만 position을 리셋하고 싶을 때 활용합니다.

<!-- 반응형에서 position 리셋 -->
<div class="ps sm-pi t0">
  데스크탑: sticky 고정
  모바일(768px 이하): initial(static)로 리셋
</div>

반응형 조합

미디어 쿼리 프리픽스와 조합하여 화면 크기에 따라 position을 변경할 수 있습니다.

<!-- 데스크탑 sticky → 모바일 static -->
<nav class="ps sm-pst t0">
  데스크탑에서는 스크롤 시 고정, 모바일에서는 일반 흐름
</nav>

<!-- 데스크탑 fixed 헤더 → 모바일 static -->
<header class="pf sm-pst t0 l0 r0">
  데스크탑에서는 고정 헤더, 모바일에서는 일반 배치
</header>
클래스 조합동작
ps sm-pst t0기본 sticky → 768px 이하에서 static
pf md-pst t0 l0 r0기본 fixed → 1024px 이하에서 static
pst sm-ps t0기본 static → 768px 이하에서 sticky
pa md-pr기본 absolute → 1024px 이하에서 relative
ps lg-pst t0기본 sticky → 1280px 이하에서 static

팁 & 주의사항

pa는 반드시 pr 부모가 필요

pa는 가장 가까운 positioned 조상을 기준으로 배치됩니다. 부모에 pr이 없으면 뷰포트 기준이 되어 의도치 않은 위치에 표시됩니다.

pf는 부모가 아닌 뷰포트 기준

pf는 항상 뷰포트를 기준으로 배치됩니다. 부모 요소의 위치와 무관하게 동작하므로, 전체 화면에서의 위치를 지정하세요.

ps에는 스크롤 컨테이너가 필요

ps는 스크롤 가능한 부모 안에서만 작동합니다. 부모에 oh(overflow: hidden)가 설정되어 있으면 sticky가 동작하지 않습니다.

z-index는 positioned 요소에만 적용

zi10 등의 z-index 클래스는 pst(static) 이외의 position 값이 설정된 요소에서만 작동합니다.