CSS 입문 4편 - Grid로 레이아웃 잡기

Grid가 등장한 이유
Flexbox로 대부분의 레이아웃은 해결되지만, 복잡한 2차원 레이아웃(행과 열을 동시에 제어)은 여전히 까다로웠어요.
처음에 Grid가 어려워 보여서 한참 미뤘는데, 막상 배우니까 Flexbox보다 간단한 경우도 많더라고요. 특히 갤러리 레이아웃은 Grid가 압도적이에요.
예를 들어 이런 레이아웃을 만든다고 생각해보세요:
Flexbox로도 가능하지만 중첩이 필요해요. Grid는 이걸 한 번에 해결합니다!
Grid 기본 구조
<div class="container">
<div class="item">1</div>
<div class="item">2</div>
<div class="item">3</div>
<div class="item">4</div>
</div>
.container {
display: grid;
grid-template-columns: 200px 200px 200px; /* 3개 열 */
grid-template-rows: 100px 100px; /* 2개 행 */
gap: 10px;
}
실행 결과:
이렇게만 해도 2행 3열 그리드가 완성됩니다!
행과 열 정의하기
1. 고정 크기
.container {
display: grid;
grid-template-columns: 100px 200px 300px; /* 각각 다른 크기 */
}
2. fr 단위 (fraction) ⭐ 가장 많이 씀
남은 공간을 비율로 나눠요.
.container {
display: grid;
grid-template-columns: 1fr 2fr 1fr; /* 1:2:1 비율 */
}
실행 결과:
가운데 열이 나머지보다 2배 넓어집니다!
3. repeat() 함수
같은 값 반복할 때 편해요.
/* 이전 방식 */
grid-template-columns: 1fr 1fr 1fr 1fr;
/* repeat 사용 */
grid-template-columns: repeat(4, 1fr); /* 4개 열, 각 1fr */
실행 결과:
4개의 열이 균등하게 배치됩니다
4. auto-fit / auto-fill ⭐ 반응형에 필수
화면 크기에 맞춰 자동으로 열 개수가 조정돼요.
.container {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
gap: 20px;
}
실행 결과:
브라우저 창 크기를 조절하면 자동으로 열 개수가 변경됩니다
- 최소 250px
- 공간이 있으면 늘어남
- 공간이 부족하면 자동으로 다음 줄로
미디어 쿼리 없이 반응형 완성!
간격(Gap)
.container {
display: grid;
grid-template-columns: repeat(3, 1fr);
gap: 20px; /* 행과 열 간격 모두 20px */
}
실행 결과:
모든 아이템 사이에 20px 간격이 있습니다
.container {
display: grid;
grid-template-columns: repeat(3, 1fr);
row-gap: 30px; /* 행 간격 */
column-gap: 20px; /* 열 간격 */
}
아이템 배치
1. grid-column / grid-row
아이템이 차지할 공간을 지정해요.
.item1 {
grid-column: 1 / 3; /* 1번 선부터 3번 선까지 (2칸 차지) */
}
선(Line) 번호:
빨간색 선이 그리드 라인 번호예요. A는 1번 선부터 2번 선까지 차지합니다.
/* 더 간단한 방법 */
.item1 {
grid-column: span 2; /* 2칸 차지 */
}
실행 결과:
첫 번째 아이템이 2칸을 차지합니다
2. 실전 예제: 헤더가 전체 너비
<div class="layout">
<header>Header</header>
<aside>Sidebar</aside>
<main>Main</main>
<footer>Footer</footer>
</div>
.layout {
display: grid;
grid-template-columns: 200px 1fr;
grid-template-rows: auto 1fr auto;
min-height: 100vh;
gap: 10px;
}
header {
grid-column: 1 / 3; /* 1열부터 3열까지 (전체 너비) */
background: #333;
color: white;
padding: 1rem;
}
aside {
background: #f0f0f0;
padding: 1rem;
}
main {
background: white;
padding: 2rem;
}
footer {
grid-column: 1 / 3; /* 전체 너비 */
background: #333;
color: white;
padding: 1rem;
}
실행 결과:

grid-template-areas (이름으로 배치)
더 직관적인 방법이에요!
.layout {
display: grid;
grid-template-columns: 200px 1fr;
grid-template-rows: auto 1fr auto;
grid-template-areas:
"header header"
"sidebar main"
"footer footer";
gap: 10px;
min-height: 100vh;
}
header { grid-area: header; }
aside { grid-area: sidebar; }
main { grid-area: main; }
footer { grid-area: footer; }
실행 결과:
grid-template-areas로 명확하게 레이아웃을 정의했습니다
시각적으로 레이아웃이 보이죠? 유지보수하기 엄청 편해요!
아이템 정렬
Container 정렬 (모든 아이템)
.container {
display: grid;
justify-items: center; /* 가로 정렬 */
align-items: center; /* 세로 정렬 */
}
실행 결과:
모든 아이템이 셀 중앙에 배치됩니다
옵션: start, end, center, stretch
개별 아이템 정렬
.item1 {
justify-self: end; /* 이 아이템만 오른쪽 정렬 */
align-self: center; /* 이 아이템만 세로 중앙 */
}
전체 Grid 정렬
Grid 전체를 컨테이너 안에서 정렬해요.
.container {
display: grid;
grid-template-columns: repeat(3, 200px);
justify-content: center; /* Grid 자체를 가로 중앙 */
align-content: center; /* Grid 자체를 세로 중앙 */
height: 100vh;
}
실전 예제 1: 사진 갤러리
<div class="gallery">
<img src="1.jpg" alt="">
<img src="2.jpg" alt="" class="wide">
<img src="3.jpg" alt="">
<img src="4.jpg" alt="" class="tall">
<img src="5.jpg" alt="">
<img src="6.jpg" alt="">
</div>
.gallery {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
grid-auto-rows: 200px; /* 행 높이 명시 */
gap: 15px;
}
.gallery img {
width: 100%;
height: 100%;
object-fit: cover;
border-radius: 8px;
}
/* 특정 이미지만 크게 */
.wide {
grid-column: span 2;
}
.tall {
grid-row: span 2;
}
실행 결과:
이미지
(tall)
특정 이미지만 크게 표시하는 갤러리 레이아웃 (넓은 이미지는 2칸, 높은 이미지는 2행을 차지)
Pinterest 스타일 갤러리 완성!
실전 예제 2: 카드 그리드
<div class="card-grid">
<div class="card">Card 1</div>
<div class="card featured">Featured</div>
<div class="card">Card 3</div>
<div class="card">Card 4</div>
<div class="card">Card 5</div>
</div>
.card-grid {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(250px, 1fr));
gap: 20px;
}
.card {
background: white;
border: 1px solid #ddd;
border-radius: 8px;
padding: 2rem;
min-height: 200px;
}
/* 강조 카드는 2칸 차지 */
.featured {
grid-column: span 2;
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
color: white;
}
실행 결과:
강조 카드가 2배 넓게 표시됩니다
실전 예제 3: 대시보드 레이아웃
<div class="dashboard">
<header>Dashboard</header>
<nav>Menu</nav>
<main>Main Content</main>
<aside>Widget</aside>
<footer>Footer</footer>
</div>
.dashboard {
display: grid;
grid-template-columns: 200px 1fr 250px;
grid-template-rows: 60px 1fr 50px;
grid-template-areas:
"header header header"
"nav main aside"
"nav footer footer";
gap: 10px;
height: 100vh;
}
header {
grid-area: header;
background: #2c3e50;
color: white;
padding: 1rem;
display: flex;
align-items: center;
}
nav {
grid-area: nav;
background: #34495e;
color: white;
padding: 1rem;
}
main {
grid-area: main;
background: white;
padding: 2rem;
overflow-y: auto;
}
aside {
grid-area: aside;
background: #ecf0f1;
padding: 1rem;
}
footer {
grid-area: footer;
background: #2c3e50;
color: white;
padding: 1rem;
display: flex;
align-items: center;
}
실행 결과:
Main Content
대시보드 주요 콘텐츠 영역
전문적인 대시보드 레이아웃을 grid-template-areas로 간단하게 구현
minmax() 함수
최소/최대 크기를 동시에 지정해요.
.container {
display: grid;
grid-template-columns: minmax(200px, 400px) 1fr;
}
실행 결과:
왼쪽 열은 최소 200px, 최대 400px로 제한됩니다
첫 번째 열은 최소 200px, 최대 400px까지만 늘어납니다.
/* 반응형 그리드의 정석 */
.container {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
}
Grid vs Flexbox 선택 기준
Flexbox 사용:
- 1차원 레이아웃 (한 줄 또는 한 열)
- 요소 크기가 불규칙적
- 아이템 순서가 중요
- 예: 네비게이션 바, 버튼 그룹
Grid 사용:
- 2차원 레이아웃 (행과 열 동시)
- 정확한 위치 지정 필요
- 전체 페이지 레이아웃
- 예: 대시보드, 갤러리, 복잡한 페이지
실무 팁: 대부분은 둘 다 섞어 씁니다. Grid로 전체 레이아웃 잡고, 각 영역 안에서 Flexbox 사용!
.container {
display: grid; /* 전체 레이아웃 */
grid-template-columns: 1fr 3fr;
}
.header {
display: flex; /* 헤더 내부는 Flexbox */
justify-content: space-between;
}
반응형 Grid 패턴
패턴 1: 자동 조정
.grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
gap: 20px;
}
미디어 쿼리 필요 없음!
패턴 2: 미디어 쿼리 활용
.grid {
display: grid;
grid-template-columns: repeat(4, 1fr);
gap: 20px;
}
@media (max-width: 1024px) {
.grid {
grid-template-columns: repeat(3, 1fr);
}
}
@media (max-width: 768px) {
.grid {
grid-template-columns: repeat(2, 1fr);
}
}
@media (max-width: 480px) {
.grid {
grid-template-columns: 1fr;
}
}
개발자 도구로 Grid 확인하기
F12 누르고 grid 컨테이너 선택하면 grid 아이콘이 보여요. 클릭하면:
- 그리드 라인이 화면에 표시됨
- 행/열 번호 확인 가능
- 영역(area) 이름 표시
Grid 배울 때 개발자 도구 없으면 정말 힘들어요!
운영자 실전 노트
실제 프로젝트 진행하며 겪은 문제
- grid 템플릿 복잡도 → 처음에
grid-template-columns: 1fr 2fr 1fr 100px처럼 복잡하게 정의.repeat()와auto-fit사용하니 간단해졌다 - auto-fit vs auto-fill 혼동 → 빈 공간 처리가 다름. 남은 공간을 채우려면
auto-fit사용한다 - 간격 조정 실패 → margin으로 조정하다가 복잡해짐.
gap속성 하나로 해결된다
이 경험을 통해 알게 된 점
- 3컬럼 이상은 Grid, 1-2컬럼은 Flexbox가 효율적이다
- grid-template-areas로 레이아웃을 시각적으로 정의하면 가독성이 좋다
다음 단계
다음 글에서는 색상과 타이포그래피를 배운다. 기능적인 레이아웃에 시각적 디자인을 입히는 법을 다룰 예정이다.
실습 과제:
- 3행 4열 그리드 만들어보기
- 특정 아이템이 2칸 차지하게 만들기
- auto-fit으로 반응형 카드 그리드 만들기
- grid-template-areas로 블로그 레이아웃 만들기
개발자 도구의 Grid 시각화 기능을 활용하면 더 빠르게 익힐 수 있다.
시리즈 네비게이션
- 이전글: CSS 독학 가이드 - Flexbox 완벽 가이드
- 현재글: CSS 독학 가이드 - Grid 레이아웃
- 다음글: CSS 독학 가이드 - 색상과 타이포그래피