이번 편의 결과물: 프로젝트 페이지의 카드 6개가 데스크톱 폭에서 3열 그리드로 배열됩니다. · 다루는 개념: grid 컨테이너, grid-template-columns와 fr 단위, gap
이 편에서 만드는 파일
web-practice/portfolio/
└ css/
└ styles.css ~ (.project-grid 규칙 추가)개념 정리
지금까지 배운 Flexbox는 한 방향(가로 또는 세로)으로 아이템을 나열하는 1차원 레이아웃입니다. 프로젝트 카드처럼 가로와 세로를 동시에 맞춰야 하는 배열에는 2차원 레이아웃인 CSS Grid가 더 알맞습니다.
| 속성 | 역할 |
|---|---|
display: grid | 요소를 grid 컨테이너로 만든다. 자식(grid item)이 트랙에 배치된다 |
grid-template-columns | 열의 개수와 각 열의 너비를 정의한다 |
fr 단위 | 남는 공간을 비율로 나눠 갖는 단위. 1fr 1fr 1fr은 셋으로 균등 분배 |
gap | 행과 열 사이 간격을 한 번에 지정한다(Flexbox의 gap과 같은 속성) |
grid-template-columns: repeat(3, 1fr)은 1fr 1fr 1fr을 줄여 쓴 표현입니다. repeat(반복 횟수, 트랙 크기) 형태로, 열 개수가 늘어나도 반복 부분만 고치면 됩니다.
fr 단위는 픽셀 같은 고정 단위와 다릅니다. 컨테이너 너비에서 gap을 뺀 나머지 공간을 지정한 비율대로 나눕니다. 1fr 1fr 1fr이면 세 열이 항상 똑같이 나눠 가지므로, 화면 폭이 바뀌어도 매번 값을 다시 계산할 필요가 없습니다.
자주 하는 오해: display: grid를 잊고 grid-template-columns만 쓰면 아무 효과가 없습니다. grid-template-columns는 요소가 이미 grid 컨테이너일 때만 의미가 있는 속성입니다.
실습
1. 기존 마크업 확인하기
projects.html의 카드 6개는 .project-grid 하나가 감싸고 있습니다. 이 편에서는 마크업을 고치지 않습니다.
<!-- projects.html (수정하지 않음, 구조만 참고) -->
<div class="project-grid">
<article class="project-card" data-tags="JavaScript,PWA">
<img src="images/project-01.svg" alt="오늘의 날씨 카드 썸네일" width="1200" height="800" />
<h2>오늘의 날씨</h2>
<p>위치 기반 날씨를 카드로 보여주는 웹앱입니다. 오프라인에서도 마지막 데이터를 보여줍니다.</p>
</article>
<!-- 카드 2~6도 같은 구조 -->
</div>지금은 .project-grid에 아무 스타일이 없어 카드 6개가 세로로 한 줄씩 쌓여 있습니다(블록 요소의 기본 흐름).
2. css/styles.css에 grid 규칙 작성하기
/* css/styles.css (일부) */
.project-grid {
display: grid;
grid-template-columns: repeat(3, 1fr);
gap: var(--space-6);
}3. 실행
projects.html을 브라우저로 열거나 새로고침합니다.
4. 확인
- 카드 6개가 3열 2행으로 배열됩니다.
- 카드 사이 가로·세로 간격이
--space-6만큼 일정합니다. - 브라우저 폭을 줄이면 열 너비는 좁아지지만 아직 열 개수(3열)는 그대로입니다. 화면 폭에 따라 열 개수를 바꾸는 작업은 14편(미디어 쿼리)에서 합니다.
미리보기 창의 폭을 좁혀 보면 fixed-grid는 고정 너비를 유지하려다 넘치고, fr-grid는 컨테이너 폭에 맞춰 세 열이 계속 균등하게 줄어듭니다.
직접 해보기
grid-template-columns를repeat(2, 1fr)로 바꿔 카드가 2열로 바뀌는지 확인한 뒤repeat(3, 1fr)로 되돌립니다.grid-template-columns: repeat(3, 1fr)을1fr 2fr 1fr로 바꿔 가운데 열만 두 배 넓어지는 것을 확인합니다.
답 보기
/* 확인용 임시 실습. 확인 후 repeat(3, 1fr)로 되돌린다 */
.project-grid {
display: grid;
grid-template-columns: 1fr 2fr 1fr;
gap: var(--space-6);
}1fr 2fr 1fr은 전체 남는 공간을 1:2:1 비율로 나눕니다. 가운데 열이 양옆 열보다 두 배 넓어집니다.
자주 하는 실수
| 증상 | 원인 | 고치는 법 |
|---|---|---|
| grid-template-columns를 줘도 카드가 그대로 쌓인다 | display: grid를 빠뜨림 | .project-grid에 display: grid 확인 |
| 카드 사이 간격이 없다 | gap을 지정하지 않음 | .project-grid에 gap: var(--space-6) 추가 |
| 화면이 좁을 때 카드가 너무 찌그러진다 | 고정 px 단위로 열을 지정함 | fr 단위로 바꿔 비율 기반으로 분배 |