css · high priority
CSS Layout — Flexbox · Grid 의 *내부 알고리즘*
*1D 흐름* 과 *2D 격자* 의 분기, `flex-grow/shrink/basis` 와 `fr`·`minmax()` 의 정확한 의미
학습 개요
탄생 배경
쉬운 설명
복잡한 개념을 실생활 비유로 설명합니다.
“*책상 정리 (Flex)* vs *책장 칸막이 (Grid)*”
Flexbox 는 *책상 위에 책들을 한 줄로 세우는 일* 입니다. 책 두께(콘텐츠) 에 따라 자동으로 자리가 정해지고, 좁아지면 *비율대로 더 좁혀지며* 들어갑니다. Grid 는 *책장에 칸막이를 먼저 짜고* 그 칸에 어떤 책을 어디에 꽂을지 정하는 일입니다. *어떤 칸은 두 칸을 합쳐* 두꺼운 책을, *다른 칸은 빈 칸으로* 둘 수도 있고, 책의 두께와 무관하게 칸의 모양이 *먼저* 결정됩니다. 책 진열대(컴포넌트 내부) 정렬은 Flex, 서재 전체(페이지) 의 칸 짜기는 Grid — 같은 서재에서 두 도구가 *함께* 일합니다.
핵심 개념
같은 문제를 두 도구로 풀 때 *드러나는 차이*
- 1차원 — 한 번에 *행 또는 열* 중 하나
- *콘텐츠 크기* 를 출발점으로 공간을 *분배*
- 아이템 수가 *런타임에 변함* — 잘 어울림
- 버튼 그룹·네비게이션·태그 칩 같은 *작은 정렬*
gap,space-between,align-items가 주 도구
1.toolbar {2 display: flex;3 align-items: center;4 gap: 12px;5}6.toolbar > .spacer { flex: 1; } /* 공간 채우기 */
- 2차원 — *행과 열* 을 동시 정의
- *먼저 격자를 그리고* 거기에 콘텐츠를 *배치*
- 아이템 수가 *알려져 있고 형태가 정해짐* — 적합
- 페이지 레이아웃·카드 그리드·대시보드
grid-template,fr,minmax,auto-fill/fit이 주 도구
1.dashboard {2 display: grid;3 grid-template-columns: 240px 1fr;4 grid-template-rows: 64px 1fr;5 min-height: 100vh;6}
실무 결정 휴리스틱 — *섞어 쓰는 게 정답*
*페이지 외곽* (사이드바 + 메인) 은 Grid, *섹션 안의 카드 그리드* 도 Grid, *카드 한 장 안의 헤더 + 본문 + 액션* 은 Flex, *툴바 안의 아이콘 정렬* 도 Flex. *둘 중 하나만 골라야 한다* 는 가정 자체가 함정이다.
의사결정 한 줄 가이드
*아이템 사이즈에 따라 줄바꿈만 하면 되면* Flexbox flex-wrap. *행과 열의 정렬이 동시에* 필요하면 Grid. 정렬만이 아닌 *카드 폭 자체가 일관* 돼야 하면 Grid.
동등한 너비 카드 N열
Flex 의 flex: 1 N 개도 가능하지만, *행 수가 바뀌면* 어색해진다. Grid 의 repeat(N, 1fr) 또는 repeat(auto-fill, minmax(...)) 가 *훨씬 안정*.
*콘텐츠가 자기 폭을 결정* 하게 두고 싶다
Flex 의 *기본 동작* 이 정확히 그것 — flex: 0 1 auto (기본) 가 *콘텐츠 크기에서 출발해 부족하면 줄어듦*. Grid 는 *명시적 트랙* 을 쓰는 도구라 의도가 다름.
실무 적용
어떤 상황에서 사용하는가
대시보드 페이지 레이아웃 + *반응형 카드 그리드* + 카드 내부 정렬을 구현하면서, *카드 안의 긴 제목이 컨테이너를 뚫는* 버그도 잡아야 한다.
어떻게 적용하는가
(1) 페이지 외곽은 Grid 의 `grid-template-areas` 로 *헤더 / 사이드바 / 메인 / 푸터* 를 7~8 줄에 표현. 사이드바가 없는 모바일은 `@media` 한 곳에서 영역만 재배치. (2) 카드 그리드는 `grid-template-columns: repeat(auto-fill, minmax(280px, 1fr))` 로 *미디어 쿼리 없이* 반응형. *카드를 적게 넣어도 공간을 꽉 채우고 싶다면* `auto-fit`. *fr 트랙이 콘텐츠로 부푸는 문제* 를 미연에 방지하려면 `minmax(0, 1fr)` 패턴을 기본으로. (3) 카드 내부 (이미지/제목/설명/버튼) 는 *Flex 컬럼* 으로 — 제목과 설명은 자연스러운 흐름, 버튼은 `margin-top: auto` 로 카드 바닥에 붙임. (4) 카드 안 텍스트가 컨테이너를 뚫는 문제는 거의 항상 *flex 자식의 `min-width: auto`* 때문 — 해당 자식에 `min-width: 0` 을 명시하면 정상화. (5) `gap` 으로 간격 통일 (margin 핵 금지). (6) 다크 모드/접근성 검증은 별도 — 이 단계에선 *레이아웃 알고리즘이 의도대로 분배되는지* 만 본다.
흔한 실수와 안티패턴
- `flex: 1` 만 쓰고 *basis 가 0* 이라는 사실을 잊어 콘텐츠 크기가 무시됨.
- `min-width: 0` 트릭을 모르고 *flex 자식이 컨테이너를 뚫음*.
- `fr` 트랙이 *콘텐츠로 부푸는 것* 을 모르고 *다른 트랙을 압박* 받음 → `minmax(0, 1fr)`.
- `auto-fill` vs `auto-fit` 차이를 모르고 *카드가 적을 때 비어 보임* (또는 그 반대).
- Flex 의 `gap` 이 모던 브라우저에서 동작함을 모르고 *margin 핵* 유지.
- `grid-template-areas` 의 *영역명이 자식의 `grid-area` 와 안 맞아* 빈 칸이 생김.
흔한 오해
*"Grid 가 새로 나왔으니 Flexbox 를 쓸 일은 없다"*
교정*해결 문제가 다르다*. 1차원 정렬에 Grid 를 쓰면 *과한 도구* 다. 콘텐츠 크기 기반 흐름은 Flex 가 더 적합.
왜 중요Flex 는 *콘텐츠 크기에서 출발*, Grid 는 *명시 격자에서 출발*. 출발점이 다르면 결과의 자연스러움도 다르다.
*"`flex: 1` 은 모든 아이템을 균등 분배"*
교정*basis 가 0* 으로 강제되어 콘텐츠 크기를 무시하고 *grow 비율로* 균등 분배되는 것일 뿐. 콘텐츠 보존이 필요하면 `flex: auto` (basis: auto) 가 정답.
왜 중요`flex: 1` 의 단축 풀이는 `1 1 0%` 다. `auto` 와 명백히 다른 동작.
*"Flex 자식은 부모를 뚫지 않는다"*
교정Flex 자식의 *기본 `min-width: auto`* 가 *내용의 가장 긴 단어/이미지* 라 정상이다. `min-width: 0` 으로 *축소를 허용* 해야 안전하다.
왜 중요디폴트가 *콘텐츠 보호* 쪽이라 의도치 않은 부풀음이 자주 일어난다 — 거의 모든 큰 코드베이스에 reset 으로 박혀 있다.
*"`fr` 은 백분율과 같다"*
교정`%` 는 *컨테이너 전체 크기* 의 비율, `fr` 은 *gap 과 고정 트랙을 뺀 남은 공간* 의 비율. 의미가 다르다.
왜 중요`gap` 이나 고정 사이드바가 들어가면 % 계산은 *직접 빼야* 하지만 fr 은 *자동* 으로 처리.
면접 질문
답변 방향 힌트
"basis 0 vs basis auto" 가 핵심.
반드시 언급할 키워드
- `flex: 1` = `1 1 0%` — basis 0 강제
- `flex: 1 1 0` 동치
- `flex: 1 1 auto` — basis 가 *콘텐츠* — 균등이 깨질 수 있음
- `flex: auto` = `1 1 auto`
- 균등 분배의 정체: basis 0 + 자유공간 균등 = 결국 *컨테이너 폭의 균등*
예상 꼬리 질문
- `flex-basis: 0` 과 `flex-basis: 0%` 의 *미묘한 차이* 가 있나요?
- `flex: none` 은 어떤 상황에 적절한가요?
자기 점검
`flex: 1` 의 *단축 풀이* 를 답하라.
기대 키워드
자주 하는 오해
*"basis auto"* — `1` 만 쓰면 basis 가 *0* 으로 강제됨.
`auto-fill` 과 `auto-fit` 의 *카드 1 개일 때* 동작 차이를 한 문장으로.
기대 키워드
자주 하는 오해
*"둘이 같다"* — 카드가 적을 때만 차이가 *극명* 하다.
Flex 자식이 부모를 뚫는 가장 흔한 원인과 해결책 한 줄.
기대 키워드
자주 하는 오해
*"`overflow: hidden` 만 답"* — 가능하지만 *축소 허용* 이 더 정확한 의도.
*미디어 쿼리 없는* 반응형 카드 그리드의 표준 한 줄.
기대 키워드
자주 하는 오해
*"미디어 쿼리 없이는 불가능"* — `auto-fill/fit` + `minmax` 가 표준.
학습 자료
- MDN — Basic concepts of flexboxFlex 알고리즘과 `flex-grow/shrink/basis` 의 *정본*.DocMDN
- MDN — Basic concepts of grid layoutGrid 트랙 · 라인 · 영역 모델의 표준 문서.DocMDN
- An Interactive Guide to Flexbox시각적 예시로 *grow/shrink/basis* 의 동작을 정확히 보여줌.BlogJosh W Comeau
- A Complete Guide to FlexboxFlexbox *치트시트* — 북마크용 레퍼런스.BlogCSS-Tricks
- A Complete Guide to CSS GridGrid *치트시트* — 모든 속성과 함수.BlogCSS-Tricks
- MDN — `minmax()``minmax(0, 1fr)` 등 트랙 크기 함수의 정확한 의미.DocMDN