03 — Flexbox & Grid
이 챕터가 답하는 질문: 1차원과 2차원, 두 레이아웃 모델 중 무엇을 언제 선택하는가?
한 줄 답 (Pyramid Top)
Flexbox는 1차원(한 축) 정렬, Grid는 2차원(양 축) 배치다. 둘은 경쟁 관계가 아니라 계층 관계 — 페이지의 큰 골격은 Grid, 그 안의 인라인 정렬은 Flex로 짠다.
Why — 왜 두 모델인가
CSS 2.1 시대에는 float·table·inline-block 조합으로 모든 레이아웃을 짰다. 결과는 두 가지 문제로 수렴했다.
- 수직 정렬이 어렵다 — vertical-align hack, table-cell 흉내, 마진 음수 등 수십 가지 우회.
- 2차원 배치가 불가능하다 — 행과 열을 동시에 제어하려면 중첩 float + clearfix로 깨지기 쉬운 구조가 된다.
CSSWG는 이를 두 단계로 해결했다.
- 2009 Flexbox — 한 축 위에서 늘리고/줄이고/정렬하는 1차원 도구.
display: flex가 일으킨 혁명은 콘텐츠 기반 자동 분배다. - 2017 Grid — 행과 열을 동시에 설계하는 2차원 도구. 콘텐츠가 아니라 컨테이너가 트랙을 정의한다.
두 모델은 의도적으로 다른 차원을 잡는다. 한 모델로 모든 걸 하려는 시도가 깨지는 이유다.
How — 어떻게 정리했나
이 챕터는 두 모델을 축 → 항목 → 사이징 → 비교의 순서로 다룬다.
| # | 파일 | 다루는 것 | 핵심 키워드 |
|---|---|---|---|
| 1 | 01-flexbox-axes | main/cross 축, direction, gap, align/justify | flex-direction, gap, align-items, justify-content |
| 2 | 02-flex-item | flex shorthand, grow/shrink/basis, min-width 함정 | flex: 1 1 0, min-width: 0, flex-basis |
| 3 | 03-grid-basics | template, fr 단위, gap, areas | grid-template, fr, repeat, gap |
| 4 | 04-grid-placement | grid-area, span, implicit grid, dense | grid-column, grid-row, dense, auto-flow |
| 5 | 05-intrinsic-sizing | minmax, min/max-content, auto-fill/fit | minmax, auto-fill, auto-fit, min-content |
| 6 | 06-subgrid | Subgrid, Masonry, 중첩 그리드 | subgrid, masonry, nested |
| 7 | 07-flexbox-vs-grid | 선택 기준, 함께 쓰는 패턴 | choose, combine, anti-patterns |
What — 이 챕터의 범위
- CSS Flexible Box Layout Module Level 1 — flex container/item, gap (2021 추가)
- CSS Grid Layout Module Level 2 — subgrid (2023 Safari, 2023 Chrome 117)
- CSS Grid Layout Module Level 3 — masonry (논쟁 중, 별도 모듈 분리 제안)
- CSS Box Alignment Module Level 3 —
place-items,place-content, gap 표준화 - CSS Sizing Module Level 3 — min-content, max-content, fit-content, minmax
브라우저 호환성은 Baseline 2024 기준 — Subgrid는 모든 evergreen에서 지원, Masonry는 Safari만 실험 구현.
What-if — 잘못 쓰면
| 증상 | 원인 | 해결 |
|---|---|---|
| flex item 안의 텍스트가 부모를 뚫고 나간다 | min-width: 0 누락 — flex item 기본 min-width: auto | min-width: 0 명시 |
flex: 1로 분배했는데 칸이 같지 않다 | flex: 1 1 auto가 콘텐츠 폭부터 시작 | flex: 1 1 0로 0부터 균등 분배 |
grid-template-columns: repeat(3, 1fr)인데 한 칸이 콘텐츠 폭만큼 커진다 | fr은 minmax(auto, 1fr)이라 콘텐츠 최소가 우선 | minmax(0, 1fr)로 명시 |
auto-fit으로 카드 그리드를 짰는데 카드 1개일 때 100%를 차지한다 | auto-fit은 빈 트랙을 0으로 접고 채운 트랙이 늘어남 | 의도면 OK, 카드 폭 유지하려면 auto-fill |
| Subgrid를 썼는데 행이 정렬되지 않는다 | 부모가 display: grid이고 같은 축에 트랙이 정의되어 있어야 함 | 부모 template 확인, grid-template-rows: subgrid |
Insight — 두 모델의 철학 차이
Flexbox와 Grid의 가장 큰 차이는 누가 트랙을 정의하느냐다.
- Flexbox: 콘텐츠가 트랙을 만든다 —
flex-basis: auto가 기본, 항목이 늘어나면 줄이 생긴다. - Grid: 컨테이너가 트랙을 만든다 —
grid-template-columns: 200px 1fr 100px을 먼저 선언하고, 항목은 그 격자에 배치된다.
이 차이는 데이터의 방향성을 반영한다.
- 메뉴, 태그, 칩, 토큰 리스트 — 순서는 있지만 격자는 없다 → Flexbox.
- 대시보드, 캘린더, 갤러리, 카드 그리드 — 격자 자체가 의미를 갖는다 → Grid.
이 챕터의 마지막 문서(07-flexbox-vs-grid)는 그 선택 기준을 8가지 패턴으로 정리한다.
요약 + Mermaid
- Flexbox는 1차원, Grid는 2차원.
- 두 모델은 계층적으로 함께 쓴다 — Grid 안에 Flex, Flex 안에 Grid.
min-width: 0/minmax(0, 1fr)두 패턴이 가장 흔한 함정.- Subgrid는 2024년 사실상 표준, Masonry는 아직 논쟁 중.
다음: 01-flexbox-axes부터 순서대로.