본문 바로가기
StyleSheet/CSS

[CSS] Positioning

반응형

우리가 직전 06단계에서 배웠던 Block과 Inline의 법칙은 브라우저의 아주 정직한 '일반 흐름(Normal Flow)'을 따릅니다. 위에서부터 아래로, 왼쪽에서 오른쪽으로 차곡차곡 박스를 쌓아가는 방식이죠. 하지만 현대의 웹 디자인은 결코 정직하지 않습니다. 스크롤을 한참 내려도 상단에 끈질기게 달라붙어 있는 네비게이션 헤더(Header), 프로필 사진의 오른쪽 구석에 살짝 걸쳐서 깜빡이는 빨간색 알림(Badge) 동그라미, 그리고 화면 정중앙에 떡하니 나타나서 뒤의 내용들을 다 가려버리는 모달(Modal) 팝업창까지! 이 모든 화려한 UI들은 기존 요소들을 밀어내지 않고, 마치 포토샵의 '레이어(Layer)'처럼 공중에 붕 떠서 자신만의 3차원 Z축 공간을 확보합니다. 문서의 일반적인 흐름(중력)을 완전히 무시하고 요소를 3차원 좌표계의 원하는 픽셀 위치에 핀셋처럼 꽂아 넣는 궁극의 공간 지배 마법, 바로 CSS Position 속성입니다. absolute 때문에 레이아웃이 와르르 무너져서 울어본 경험이 있다면 필수 시청! 이번 07단계 포스팅에서는 relative와 absolute의 부모-자식 연대기, fixed와 sticky의 스크롤 통제권까지 상세히 알아보겠습니다.

1. 평범한 일상: position: static (기본값)

모든 HTML 요소는 태어날 때부터 position: static 속성을 갖습니다. 이는 위에서 아래로 쌓이는 브라우저의 일반적인 문서 흐름(Normal Flow)을 얌전하게 따른다는 뜻입니다. static 상태의 가장 중요한 특징은, CSS에서 아무리 top: 50px, left: 100px, z-index: 999 같은 좌표나 레이어 계층 명령을 내려도 철저하게 무시해버린다는 점입니다. 요소를 움직이려면 이 얌전한 상태를 깨부숴야 합니다.

2. 기준점이 되어라: position: relative

요소에 position: relative를 주면 마침내 top, left, bottom, right 좌표 명령이 먹히기 시작합니다. 기준점은 바로 '자신이 원래 있어야 할 위치'입니다. 원래 자리에서 top: 20px을 주면 아래로 20px 살짝 빗겨나게 이동합니다.

하지만 실무에서 relative를 써서 요소를 이동시키는 짓은 거의 하지 않습니다. 원래 자리가 텅 빈 여백으로 남아버려서 레이아웃이 흉해지기 때문입니다. 그렇다면 relative는 언제 쓸까요? 오직 자신의 자식 요소인 absolute가 우주로 튕겨 날아가지 않도록 붙잡아두는 '울타리(기준점)' 역할을 부여할 때만 99% 사용됩니다. 프론트엔드 세계의 영원한 국룰, "자식이 absolute면 부모는 무조건 relative다!"라는 공식을 기억하십시오.

3. 궁극의 공중 부양: position: absolute

position: absolute를 선언하는 순간, 그 요소는 무시무시한 능력을 얻게 됩니다. 기존의 문서 흐름에서 완전히 뜯겨져 나와(공중으로 붕 뜸), 자신이 원래 차지하던 공간(크기)을 완전히 잃어버립니다. 덕분에 옆에 있던 다른 요소들이 빈 공간을 훌렁 메꾸러 밀고 들어옵니다. 이제 이 요소는 topleft 값을 주면 모니터 화면의 좌측 상단(0,0)을 기준으로 날아다니게 됩니다.

💡 실무 필수 패턴: 부모 가두기 (Relative & Absolute Combo)

만약 이미지 박스(.card)의 우측 하단에 조그마한 '좋아요(♥)' 하트 버튼을 띄우고 싶다면 어떻게 해야 할까요? 하트 버튼에 absoluteright: 0; bottom: 0;을 주면, 하트는 이미지 박스를 무시하고 브라우저 전체 화면의 오른쪽 맨 아래 구석으로 도망가 버립니다. Absolute 요소는 positionstatic이 아닌 가장 가까운 '조상 요소'를 좌표의 기준으로 삼기 때문입니다.

/* 1. 부모 박스에 울타리(relative)를 친다! */
.card-box {
    position: relative; /* 자식의 좌표 기준점이 됨 */
    width: 300px; height: 300px;
}
/* 2. 자식 요소(하트)를 공중에 띄워 좌표를 꽂는다! */
.heart-btn {
    position: absolute; /* 공중 부양 */
    bottom: 10px;       /* 부모(.card-box)의 맨 아래에서 10px 위로 */
    right: 10px;        /* 부모(.card-box)의 맨 우측에서 10px 좌로 */
}

이 콤보는 알림 뱃지, 슬라이드 배너의 좌우 화살표 버튼, 이미지 위로 텍스트 겹치기 등 프론트엔드 UI를 구성하는 가장 핵심적이고 절대적인 설계 패턴입니다.

4. 뷰포트의 껌딱지: position: fixed

absolute가 부모를 기준으로 좌표를 잡는다면, position: fixed는 부모가 누구든 족보를 완전히 무시하고 오로지 '브라우저 창(Viewport)' 자체를 기준으로 공중에 고정됩니다. 화면 스크롤을 아무리 미친 듯이 내려도 우측 하단에 계속 떠 있는 '카카오톡 상담하기' 버튼이나, 스크롤을 내려도 항상 화면 맨 꼭대기에 붙어있는 '고정 네비게이션 바(Fixed Header)'를 만들 때 사용합니다. Fixed 역시 기존 흐름에서 빠져나오기 때문에, Header를 fixed로 만들면 그 아래 있던 본문 내용이 위로 쑥 빨려 올라가서 Header 밑에 깔려 가려지는 버그가 발생합니다. 반드시 본문 영역(Body) 상단에 Header 높이만큼의 padding-top을 주어 겹침을 방지하는 실무 센스가 필요합니다.

5. 차세대 스마트 접착제: position: sticky

과거에는 "평소에는 중간쯤 있다가, 스크롤을 내려서 화면 천장에 닿는 순간 위에 딱 달라붙는 메뉴바"를 만들기 위해 자바스크립트(JS)의 스크롤 이벤트를 복잡하게 짜야만 했습니다. (성능 저하의 주범!) 하지만 최신 CSS3 명세에 추가된 position: sticky를 사용하면 JS 없이 단 두 줄로 구현됩니다.

.table-header {
    position: sticky;
    top: 0; /* 스크롤을 내리다가 화면 상단(0px)에 닿으면 고정시켜라! */
}

Sticky 요소는 평소에는 relative처럼 얌전하게 문서 흐름을 타고 스크롤을 따라 올라가다가, 지정된 임계점(top: 0)에 도달하는 순간 fixed처럼 턱! 하고 화면에 달라붙습니다. [🚨 치명적 주의점] 만약 Sticky 요소의 부모 태그(조상 중 하나라도)에 overflow: hidden;이나 overflow: auto; 속성이 걸려 있다면, 스크롤 높이를 계산하지 못해 Sticky 마법이 완전히 고장 나버리니 실무 디버깅 시 반드시 부모의 overflow 속성을 체크해야 합니다!

정리하며

이번 07단계 포스팅에서는 브라우저의 평범한 Z축 중력을 무시하고 레이아웃을 3차원으로 찢어발기는 Position의 강력한 마법사들을 살펴보았습니다. relative라는 든든한 닻(Anchor)과 그 주변을 맴도는 absolute 위성의 조합은 현대 웹 UI 구성의 알파이자 오메가입니다. 자, 이제 우리는 요소를 원하는 위치에 정확히 꽂아 넣는 법을 알았습니다. 그런데, 옛날 개발자들은 Position 속성이 지금처럼 유연하지 못했던 시절, 박스들을 가로로 나란히 배치하기 위해 '이미지 옆에 글씨를 쓰게 해주는' 기괴한 속성을 해킹하여 레이아웃 전체를 짜는 미친 짓을 벌였습니다. 아직도 레거시 코드에 수만 줄 씩 남아있는 그 공포의 속성! 다음 08단계 포스팅에서는 프론트엔드 다크 에이지의 유물, "CSS Float와 Clearfix: 레이아웃 붕괴와 구시대의 해킹 기법"에 대해 뼈 때리게 파헤쳐 보겠습니다!

반응형

'StyleSheet > CSS' 카테고리의 다른 글

[CSS] Variables (사용자 지정 속성)  (0) 2026.07.28
[CSS] Float와 Clearfix  (0) 2026.07.28
[CSS] Display  (0) 2026.07.28
[CSS] 타이포그래피(Typography)  (0) 2026.07.28
[CSS] Color & Background  (0) 2026.07.28