"position 은 normal flow 의 비상구. z-index 는 탈출한 다음 어떻게 stack 되는지. 대부분의 layout 버그가 하나 또는 둘 다 오해에서 살아."
다섯 position 값
static— 기본. Element 가 normal flow 에 앉음.top/right/bottom/left효과 없음.z-index효과 없음.relative— normal flow 에 있지만, 자연 위치에서top/right/bottom/left만큼 시각적으로 offset. Element 의 예약 공간은 여전히 원래 자리. 또: absolute 자식의 positioning context 가 됨.absolute— normal flow 에서 제거. 가장 가까운 positioned ancestor (static 아닌 position 가진 어떤 ancestor) 기준 위치. Positioned ancestor 없으면 초기 containing block (문서는 viewport, iframe 은 iframe) 기준.fixed— normal flow 에서 제거. Viewport 기준 위치. 페이지 스크롤 시 안 움직임.sticky— 스크롤 임계점 도달까지 normal flow 에 있다가, 그 다음 containing block 안에서 fixed 처럼 행동. Sticky header, 행 스크롤 동안 보이는 table header 에.
Containing Block 질문
absolute positioning 에서, "뭘 기준으로 positioned?" 질문이 position 자체보다 중요. 답:
position: relative,absolute,fixed,sticky, 또는transform/filter/perspective설정된 가장 가까운 ancestor.- 그런 ancestor 없으면 초기 containing block (viewport).
Canonical 패턴: 부모가 offset 없이 position: relative, 자식이 offset 가진 position: absolute. Relative 부모가 positioning context; absolute 자식이 안에서 position.
Sticky 는 추가 주름 있음
position: sticky 가 직접 부모의 박스 안에 붙어. 전역적으로 viewport 에 안 붙음 — 부모가 스크롤로 지나가면, sticky element 도 함께 스크롤되어 사라짐. position: sticky 가 table header 에 작동하는 이유 (table 스크롤 동안 붙음); 하지만 flex/grid 자식 컨테이너 안의 position: sticky 가 종종 "작동 안 함" — 부모의 height 가 스크롤할 공간 안 허용해서.
Sticky 가 필요한 두 가지:
- 스크롤 방향 정의 (
top: 0,bottom: 0,left: 0등). - 부모의 height 가 sticky element 의 예약 height 보다 큼 (아니면 붙을 자리 없음).
z-index 와 stacking context
Element 가 overlap 될 때 (positioned 여서), z-index 가 어느 게 위에 갈지 결정. 높은 숫자 이김. 하지만 — 그게 함정 — z-index 는 같은 stacking context 안 element 만 비교.
새 stacking context 가 만들어지는 방법:
position: relative/absolute/fixed/stickyWITHauto아닌z-indexposition: fixed또는stickyz-index 무관opacity1 미만transform,filter,backdrop-filterwill-change가 stacking context 만드는 property 로 설정isolation: isolate— 모던하고 의도적 방법contain: layout,paint, 또는strictz-index설정된 Flexbox/grid 항목
클래식 혼란: modal 의 z-index: 999999 가 stacking context 설정한 부모 안에 갇혀 있으면 무관한 element 의 z-index: 10 위에 안 올라감. 그 부모 안에서 modal 은 맞게 stack; 바깥에선 부모의 stack 레벨이 중요한 거.
isolation: isolate 써. "이 영역은 자기 z-index 세계" 라고 말하는 모던하고 부작용 없는 방법. Sibling 으로 z-index 새지 않게 하고 싶은 component 의 root, 또는 부모 z-index 오염에서 보호하고 싶은 영역에 써.멀쩡한 z-index Layer 디자인
무작위 숫자 (z-index: 9999, z-index: 999999) 고르지 마. 작은 layer set 을 custom property 로 정의하고 이름으로 써:
모던 가운데 정렬 패턴
가운데 정렬이 옛날엔 정렬하는 게 뭔지 따라 패턴 셋 필요 (margin auto, line-height, table-cell, 음수 margin 가진 absolute positioning, transform translate). 모던 CSS: 부모에 display: grid; place-items: center; 가 어떤 자식이든 두 축에 가운데. display: flex; align-items: center; justify-content: center; 도 같은 거.
피파의 노트
isolation: isolate 써, 신경 쓰는 몇 layer 의 z-index 변수와 함께: --z-dropdown, --z-modal-backdrop, --z-modal, --z-toast. 변수가 layering 을 프로젝트 레벨에서 보이게; isolation 이 어떤 component 의 z-index 든 우연히 전역 stack 과 싸우는 거 방지. 마법 숫자 그만 고르고 layer 이름 짓기 시작하면 클래식 z-index 전쟁이 사라져.