CSS position relative와 absolute 차이
CSS에서 요소 위치를 옮기다 보면 position: relative와 position: absolute를 자주 만난다.
둘 다 top, right, bottom, left 같은 속성과 함께 쓰이지만, 동작 방식은 꽤 다르다.
핵심 차이는 normal flow에 남아 있는지와 어떤 기준을 보고 움직이는지다.relative는 원래 자리를 유지한 채 자기 위치를 기준으로 움직인다.absolute는 원래 자리에서 빠져나와 기준이 되는 조상 요소를 보고 움직인다.
이 차이를 모르면 배지가 엉뚱한 곳에 붙거나, 카드 안에 있어야 할 버튼이 화면 왼쪽 위로 튀는 상황을 만나기 쉽다.
position의 기본값
대부분의 HTML 요소는 기본적으로 position: static이다.static은 문서의 기본 흐름에 따라 배치된다는 뜻이다.
.box {
position: static;
}static 상태에서는 top, right, bottom, left가 위치를 바꾸지 않는다.
.box {
position: static;
top: 20px;
left: 20px;
}위 코드는 top과 left를 적었지만 실제 위치 이동에는 영향을 주지 않는다.
위치 보정 속성을 쓰려면 position 값을 relative, absolute, fixed, sticky 같은 값으로 바꿔야 한다.
relative의 기준
position: relative는 요소를 normal flow에 그대로 둔다.
브라우저는 먼저 요소를 원래 자리로 배치하고, 그 위치를 기준으로 시각적인 위치만 옮긴다.
<div class="box one">1</div>
<div class="box two">2</div>
<div class="box three">3</div>.box {
width: 80px;
height: 80px;
}
.two {
position: relative;
top: 20px;
left: 20px;
}.two는 원래 자리에서 아래로 20px, 오른쪽으로 20px 이동해 보인다.
하지만 레이아웃에서 .two가 차지하던 공간은 그대로 남는다.
그래서 .three는 .two가 이동한 위치를 피해 다시 배치되지 않는다.
relative는 작은 시각 보정에 사용할 수 있다.
하지만 더 자주 쓰이는 용도는 absolute 자식의 기준점을 만드는 것이다.
absolute의 기준
position: absolute는 요소를 normal flow에서 빼낸다.
다른 요소들은 absolute 요소가 없는 것처럼 배치된다.
<div class="card">
<span class="badge">NEW</span>
<h2>상품 이름</h2>
<p>상품 설명</p>
</div>.badge {
position: absolute;
top: 12px;
right: 12px;
}이 코드만 보면 .badge가 .card의 오른쪽 위에 붙을 것처럼 보인다.
하지만 반드시 그렇지는 않다.absolute는 가장 가까운 positioned ancestor를 기준으로 위치를 잡는다.
여기서 positioned ancestor는 position 값이 static이 아닌 조상 요소를 말한다.
가까운 조상 중 그런 요소가 없으면 문서의 초기 containing block 쪽을 기준으로 잡힐 수 있다.
그래서 배지가 카드가 아니라 화면 쪽으로 붙는 것처럼 보일 수 있다.
부모 relative 패턴
카드 안에서 배지를 오른쪽 위에 고정하고 싶다면 부모 카드에 position: relative를 준다.
.card {
position: relative;
padding: 24px;
border: 1px solid #d0d7de;
}
.badge {
position: absolute;
top: 12px;
right: 12px;
}이제 .badge는 .card를 기준으로 위에서 12px, 오른쪽에서 12px 떨어진 위치에 놓인다.
부모의 position: relative는 카드 자체를 움직이기 위한 코드가 아니다.
자식 absolute 요소가 바라볼 기준 상자를 만들기 위한 코드에 가깝다.
이 패턴은 자주 쓰인다.
카드의 라벨, 이미지 위의 버튼, 입력창 안의 아이콘, 알림 카운트 같은 UI에서 많이 만난다.
<button class="bell-button">
알림
<span class="count">3</span>
</button>.bell-button {
position: relative;
}
.count {
position: absolute;
top: -6px;
right: -6px;
}버튼은 normal flow에 남아 있고, 카운트만 버튼을 기준으로 겹쳐 올라간다.
top과 left의 의미
top과 left는 relative와 absolute에서 모두 쓸 수 있다.
하지만 기준이 다르다.
relative에서 top: 20px는 원래 자기 위치에서 아래로 20px 이동한다는 뜻이다.relative에서 left: 20px는 원래 자기 위치에서 오른쪽으로 20px 이동한다는 뜻이다.
.box {
position: relative;
top: 20px;
left: 20px;
}absolute에서 top: 20px는 containing block의 위쪽 기준선에서 20px 떨어진다는 뜻이다.absolute에서 left: 20px는 containing block의 왼쪽 기준선에서 20px 떨어진다는 뜻이다.
.box {
position: absolute;
top: 20px;
left: 20px;
}같은 속성 이름을 쓰지만, 하나는 자기 원래 위치를 기준으로 하고 다른 하나는 기준 상자를 기준으로 한다.
이 차이가 relative와 absolute를 구분하는 핵심이다.
normal flow 차이
normal flow는 브라우저가 요소를 기본 규칙대로 배치하는 흐름이다.
block 요소는 위에서 아래로 쌓이고, inline 요소는 줄 안에서 흐른다.
relative 요소는 normal flow에 남는다.
그래서 원래 차지하던 공간이 유지된다.
absolute 요소는 normal flow에서 빠진다.
그래서 주변 요소는 absolute 요소가 없는 것처럼 배치된다.
<div class="wrapper">
<div class="absolute-box">absolute</div>
<p>이 문장은 absolute 요소가 없는 것처럼 배치될 수 있다.</p>
</div>.wrapper {
position: relative;
}
.absolute-box {
position: absolute;
top: 0;
left: 0;
}이 구조에서는 .absolute-box가 p 위에 겹칠 수 있다.
겹침이 필요한 UI라면 의도한 동작이다.
하지만 문서 흐름 안에서 자연스럽게 공간을 차지해야 하는 레이아웃이라면 absolute가 맞지 않을 수 있다.
레이아웃 용도 구분
초보자일 때는 원하는 위치로 요소를 보내기 위해 absolute를 쉽게 쓰게 된다.
하지만 전체 페이지 배치나 카드 목록 정렬에는 보통 flex, grid, margin, padding이 더 적합하다.
.list {
display: flex;
gap: 16px;
}absolute는 흐름에서 빠져나오는 도구다.
그래서 반응형 화면에서 예상보다 쉽게 겹치거나, 텍스트가 길어졌을 때 다른 콘텐츠를 가릴 수 있다.
화면 전체 배치를 만들고 싶다면 먼저 일반 레이아웃 도구를 본다.
특정 요소를 부모 안의 모서리에 붙이거나 겹쳐야 한다면 relative 부모와 absolute 자식 패턴을 고려한다.
z-index와 겹침
absolute를 쓰면 요소가 다른 요소와 겹치는 상황이 자주 생긴다.
이때 z-index로 앞뒤 순서를 조정할 수 있다.
.card {
position: relative;
}
.badge {
position: absolute;
z-index: 1;
}z-index는 숫자가 클수록 앞쪽에 놓이는 식으로 이해하면 된다.
다만 복잡한 화면에서는 stacking context 때문에 단순 숫자 비교만으로 설명되지 않는 경우가 있다.
처음에는 겹치는 UI 범위를 작게 유지하는 편이 좋다.
카드 안의 배지처럼 부모와 자식 관계가 분명한 곳에서 쓰면 추적하기 쉽다.
선택 기준
원래 자리를 유지하면서 살짝 움직이고 싶다면 relative를 쓴다.
absolute 자식의 기준점을 만들고 싶을 때도 부모에 relative를 둔다.
부모나 기준 상자를 기준으로 모서리에 붙이거나 겹치게 배치하고 싶다면 absolute를 쓴다.
다만 absolute 요소는 normal flow에서 빠진다는 점을 먼저 생각한다.
정리하면 기준은 단순하다.
공간을 유지하면 relative다.
공간에서 빠져나오면 absolute다.
부모 기준 absolute가 필요하면 부모에 position: relative를 둔다.
