CSS Grid — 2차원 카드 레이아웃

줄과 칸을 동시에 다루는, 카드 목록의 정답

10초 핵심 요약

01

Flex vs Grid — 언제 뭘 써야 하나

Flexbox는 사람들을 한 줄로 세우는 것과 같습니다. 줄이 길어지면 옆으로(또는 아래로) 계속 늘어날 뿐, "몇 번째 줄, 몇 번째 칸"이라는 개념이 없습니다. Grid는 도시락통입니다. 처음부터 가로 칸과 세로 줄을 함께 그려놓고, 그 격자 안에 반찬을 하나씩 배치합니다.

헤더처럼 1방향이면 Flex, 카드 목록처럼 행과 열이 같이 바뀌면 Grid.

똑같은 상자 6개, 결과가 다릅니다 — 직접 비교해보세요
Flexbox (flex-wrap)
조금 긴 제목
아주 아주 긴 제목
중간 제목
2번째 줄 시작 위치가 1번째 줄 칸과 안 맞습니다.
Grid (3열 고정)
조금 긴 제목
아주 아주 긴 제목
중간 제목
모든 칸이 격자로 정확히 줄맞춰 있습니다.
02

기본 패턴: 3열 Grid

가장 많이 쓰는 시작 코드입니다. 부모에게 display: grid를 주고, 열 개수와 너비를 지정합니다.

/* 부모: 카드들을 감싸는 컨테이너 */
.post-list {
  display: grid;
  grid-template-columns: repeat(3, 1fr); /* 똑같은 폭 3칸 */
  gap: 20px; /* 칸 사이 간격 (Flexbox와 동일한 속성) */
}

예상해보세요: 3열에서 4열로 바꾸면 카드 하나의 크기는 커질까요, 작아질까요? 예상한 다음 버튼을 눌러 확인하세요.

1
2
3
4
5
6
.grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 8px;
}

그런데 repeat(3, 1fr)을 화면이 좁은 모바일에 그대로 쓰면 무슨 일이 벌어질까요? 실제로 260px 너비 화면에 넣어봤습니다.

오늘의 웹디자인 후기
그리드 정복하기
두 번째 이야기

글자가 다 뭉개졌습니다 — repeat(3, 1fr)이 화면 크기와 상관없이 무조건 3칸을 고집했기 때문입니다. 모바일에서 카드가 찌그러지는 원인 1위입니다.

이 문제, 3번에서 auto-fill + minmax로 해결합니다.

03

반응형 마법: auto-fill + minmax

열 개수를 숫자로 못박지 않고, "각 카드는 최소 이만큼은 확보하고, 남는 공간에 맞춰 알아서 몇 개가 들어갈지 정해라"라고 브라우저에게 맡기는 방식입니다.

.post-list {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(280px, 1fr)); /* 최소 280px 확보, 남는 공간만큼 칸 자동 생성 */
  gap: 20px;
}

auto-fill

"칸을 최대한 많이 만들어라." 카드 개수가 적어도 빈 칸 자리를 남겨둡니다.

minmax(280px, 1fr)

"각 칸은 최소 280px, 남으면 fr(비율)만큼 늘어나라." 이 최솟값 밑으로는 절대 안 줄어듭니다.

포스트 목록은 거의 항상 이 한 줄로 끝납니다: grid-template-columns: repeat(auto-fill, minmax(280px,1fr))

04

grid-template-areas — 전체 페이지 설계

카드뿐 아니라 페이지 전체(헤더/본문/사이드바/푸터)도 Grid로 그릴 수 있습니다. 지도를 그리듯 이름을 붙이는 방식이라 직관적입니다.

.wrap {
  display: grid;
  grid-template-columns: 1fr 280px; /* 왼쪽은 남는 공간 전부, 오른쪽은 280px 고정 */
  grid-template-areas: /* 아래처럼 지도를 그리듯 배치를 적습니다 */
    "header header" /* 1행: 헤더가 두 칸 다 차지 */
    "main sidebar" /* 2행: 본문과 사이드바가 나란히 */
    "footer footer"; /* 3행: 푸터가 두 칸 다 차지 */
}
.header { grid-area: header; } /* 위에서 적은 이름과 그대로 연결 */
.sidebar { grid-area: sidebar; }
초보자 1위 실수 — 각 줄을 반드시 따옴표로 감싸야 합니다. "header header"처럼요. 따옴표 하나만 빠져도 레이아웃 전체가 무너집니다.
05

오늘의 실습

1더미 카드 3~5개를 .post-list로 감싸고 repeat(auto-fill, minmax(280px,1fr))를 적용합니다.
2F12 → 반응형 모드를 켜고 화면 너비를 드래그하며 열 개수가 3 → 2 → 1로 줄어드는 지점을 관찰합니다.
3minmax의 최솟값을 280px → 400px로 바꿔보고, 한 줄에 들어가는 카드 개수가 줄어드는 걸 확인합니다.
안 될 때 확인하세요 카드가 한 줄에 계속 다 붙어 있고 줄바꿈이 안 된다면, grid-template-columnsauto-fill이나 auto-fit이 빠지고 고정 숫자만 남아있는지 확인하세요. 반대로 카드가 세로로 한 줄씩 쌓인다면 부모에 display: grid; 자체가 빠졌을 확률이 높습니다.
스스로 설명해보기 — repeat(3, 1fr) 대신 repeat(auto-fill, minmax(280px, 1fr))을 써야 하는 이유를 설명할 수 있나요?
06

Day 6 완료 체크리스트

1방향 배치는 Flex, 행+열이 함께 바뀌는 배치는 Grid라는 기준을 설명할 수 있다.
repeat(auto-fill, minmax(280px,1fr))이 반응형을 자동으로 만들어준다는 걸 이해했다.
열 너비를 px로 고정하면 반응형이 깨진다는 이유를 설명할 수 있다.

오늘의 용어

display: grid
행과 열을 동시에 다루는 2차원 레이아웃 방식
grid-template-columns
열의 개수와 너비를 정하는 속성
minmax(280px, 1fr)
최소 크기는 지키고 남는 공간은 비율대로 늘리는 지정법
auto-fill
화면 너비에 맞춰 칸 개수를 자동으로 채워주는 값