02 — 레이아웃 (Flow · Position · Sizing)
이 챕터가 답하는 질문: Flexbox/Grid를 쓰기 전에, 브라우저는 박스를 어떻게 흐름(flow) · 위치(position) · 크기(sizing) 로 배치하는가? 한 줄 답: “레이아웃은 ① 어디로 흐르는가(Normal Flow), ② 어디에 고정되는가(Position), ③ 얼마나 커지는가(Sizing)의 세 축이 합쳐진 결과다.”
한 문장 답 (Pyramid Top)
CSS 레이아웃 엔진은 Flexbox/Grid가 나오기 전부터 박스를 배치하는 세 가지 기본 메커니즘으로 동작한다 — ① Normal flow (BFC/IFC, margin collapse), ② Position (static/relative/absolute/fixed/sticky + containing block), ③ Sizing (width/height의 의미, intrinsic, aspect-ratio). 그 위에 Logical properties(RTL/세로쓰기)와 Anchor Positioning(2026 baseline)이 모던 레이어를 형성한다. Flexbox/Grid는 다음 챕터에서 다루지만, 이 챕터의 메커니즘 위에 올라타는 것이지 대체하지 않는다.
챕터 지도 (Mermaid)
Why — 왜 이 챕터부터인가
대부분의 “CSS가 의도와 다르게 동작한다” 사고는 Flexbox/Grid가 아니라 이 챕터의 기본 메커니즘에서 출발한다.
- “왜
position: sticky가 갑자기 안 붙지?” → 부모의overflow: hidden이 스크롤 컨테이너를 끊었다 →02-position. - “왜 자식
margin-top이 부모 바깥으로 새지?” → margin collapse (BFC 미형성) →01-normal-flow. - “왜
position: absolute가 의도한 부모에 안 붙지?” → 부모에transform이 걸려 containing block이 바뀜 →02-position. - “왜
width: 100%인데 부모를 삐져나가지?” → intrinsic min-content가 더 큼 →04-sizing. - “왜 모바일에서 비율이 깨지지?” →
aspect-ratio안 쓰고padding-bottom해킹 →04-sizing. - “한국어/일본어 세로쓰기를 어떻게 하지?” → Logical properties +
writing-mode→05-logical-properties. - “드롭다운 위치 계산을 JS로 매번 짜야 하나?” → Anchor Positioning + Popover API →
06-anchor-positioning.
**이 챕터는 그 모든 질문을 “어느 메커니즘에서 어떤 가정이 깨졌나”로 환원한다.
How — 어떻게 읽나
6개 문서를 순서대로 읽으면 한 시간 반 정도 걸린다. 의존성이 누적된다.
| # | 파일 | 읽는 데 | 핵심 키워드 |
|---|---|---|---|
| 01 | 01-normal-flow | 15분 | BFC, IFC, margin collapse, display: flow-root |
| 02 | 02-position | 15분 | containing block, sticky 함정, stacking context |
| 03 | 03-float-and-clear | 10분 | float 역사, shape-outside, 텍스트 흐름 |
| 04 | 04-sizing | 15분 | min/max, min-content/max-content/fit-content, aspect-ratio |
| 05 | 05-logical-properties | 12분 | block-size, inline-start, inset, writing-mode |
| 06 | 06-anchor-positioning | 12분 | anchor-name, position-area, Popover API |
의존성: 02는 01의 BFC를 안다고 가정. 03은 02의 흐름 이탈을 안다고 가정. 04는 모든 레이아웃의 토대. 05는 04를 논리축으로 추상화. 06은 05의 inset을 동적으로 계산.
What — 한 페이지 요약 (모든 문서의 핵심 한 줄)
| 문서 | 한 줄 결론 |
|---|---|
| 01 | Normal flow는 block 방향으로 쌓고 inline 방향으로 흘리는 기본 알고리즘이며, BFC를 만들면 margin collapse와 float 침범이 동시에 차단된다. |
| 02 | position은 containing block과 흐름 참여 여부를 동시에 바꾼다 — absolute의 부모는 가장 가까운 positioned 조상이지 DOM 부모가 아니다. |
| 03 | Float는 2017년 이전의 레이아웃 도구였지만, 2026년에는 텍스트 옆 이미지 흐름 + shape-outside라는 단 하나의 본업으로 돌아왔다. |
| 04 | width: 100%는 *부모 width의 100%*지만 width: max-content는 내용물의 최소 줄바꿈 없는 너비다 — 이 둘의 차이를 모르면 반응형이 깨진다. |
| 05 | margin-left는 RTL에서 의미가 뒤집히지만 margin-inline-start는 논리축이라 절대 뒤집히지 않는다. |
| 06 | Anchor Positioning은 position: absolute를 다른 요소에 종속시키는 CSS 네이티브 위치 계산이며, Popover API와 짝지어 JS 없는 툴팁/메뉴를 가능케 한다. |
What-if — 이 챕터를 건너뛰면
- 흐름 무지 →
<div>로 감싸기만 하면 margin이 새는 이유를 모름 →display: flow-root하나로 끝날 일을overflow: hidden으로 해결하다가 sticky를 죽인다. - containing block 무지 →
position: absolute부모에 무심코transform: translateZ(0)박았다가 모달이 엉뚱한 곳에 뜬다. - intrinsic sizing 무지 → 카드 내부 긴 영문 단어가 부모를 삐져나가는데
min-width: 0을 모르고 한참을 헤맨다. - logical properties 무지 → 한·중·일 세로쓰기, 아랍어 RTL을 지원하기 위해 별도 스타일시트를 두 벌 짠다.
- anchor positioning 무지 → 드롭다운 위치 계산을 floating-ui로 매번 짜는데, 2026년 baseline은 CSS만으로 끝낼 수 있다.
Insight — 한 단락 이야기
“CSS는 1996년에 문서 레이아웃을 위해 태어났다”
그래서 CSS의 기본은 흘려보내기(flow) 였다 — 책처럼 위에서 아래로 쌓고, 글자처럼 좌→우로 흐른다. 그 위에 float(신문 사진 흐름)와 position: absolute(앵커링)가 얹혔다. 이게 2009년까지의 전부였다.
2009~2017년 사이 Flexbox와 Grid가 추가되며 2D 레이아웃 엔진이 정식 명세가 됐지만, 여전히 그 모든 것은 normal flow 위에 올라탄다.
display: flex도 flex 컨테이너 안의 자식들만 flex로 배치하고, 그 컨테이너 자체는 부모의 normal flow에 따라 배치된다.2024~2026년 사이 두 가지가 더해진다 — Container Queries(컨텍스트 기반 반응형)와 Anchor Positioning(요소 기반 위치 계산). 후자는 position: absolute가 부모가 아닌 임의의 요소를 기준으로 동작할 수 있게 만든 패러다임 전환이다.
이 챕터는 그 30년 진화의 토대를 한 번에 읽는다. Flexbox/Grid는 그 위에서 빛난다.
한 단락 요약
레이아웃은 흐름·위치·크기 세 축의 합성이다. 흐름(
01)은 BFC/IFC와 margin collapse를 만들고, 위치(02)는 containing block과 stacking context를 결정하며, 크기(04)는 intrinsic과 explicit 사이의 협상이다. 그 위에 logical properties(05)로 물리 축에서 논리 축으로 추상화가 한 번 더 올라가고, anchor positioning(06)으로 위치를 동적으로 종속시키는 모던 패턴이 추가된다. 다음 챕터(03-flexbox-grid)는 이 토대 위에 2D 레이아웃 엔진을 얹는다.