Contents
see List개요
CSS Grid는 2차원 레이아웃 시스템으로, 복잡한 웹 레이아웃을 깔끔하게 구현할 수 있게 합니다. 2023년부터 모든 주요 브라우저에서 Subgrid가 지원되면서, Grid의 진가가 완전히 발휘되고 있습니다. Flexbox가 1차원(행 또는 열)이라면 Grid는 2차원(행과 열 동시)을 다루며, 복잡한 대시보드, 카드 레이아웃, 매거진 스타일 페이지에 최적화되어 있습니다.
핵심 개념
Grid Container는 display: grid를 적용한 부모 요소이며, Grid Item은 그 직접 자식 요소들입니다. grid-template-columns와 grid-template-rows로 그리드 트랙을 정의합니다.
fr 단위는 사용 가능한 공간의 비율을 나타냅니다. 1fr 2fr는 1:2 비율로 공간을 분배합니다.
Grid Lines는 그리드를 구성하는 선으로, 아이템 배치 시 참조합니다. 숫자 또는 이름으로 지정할 수 있습니다.
Subgrid는 중첩된 그리드가 부모 그리드의 트랙을 상속받아, 여러 계층의 요소를 하나의 그리드 시스템에 정렬할 수 있게 합니다.
실전 예제
기본적인 그리드 레이아웃을 구현합니다.
/* 기본 그리드 */
.grid-container {
display: grid;
grid-template-columns: repeat(3, 1fr);
grid-template-rows: auto;
gap: 1rem;
}
/* 반응형 그리드 - auto-fit, minmax 활용 */
.responsive-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
gap: 1.5rem;
}
/* 명시적 행/열 정의 */
.explicit-grid {
display: grid;
grid-template-columns: 200px 1fr 200px;
grid-template-rows: 80px 1fr 60px;
min-height: 100vh;
}
/* Grid Template Areas로 레이아웃 정의 */
.page-layout {
display: grid;
grid-template-areas:
"header header header"
"sidebar main aside"
"footer footer footer";
grid-template-columns: 200px 1fr 200px;
grid-template-rows: 80px 1fr 60px;
gap: 1rem;
min-height: 100vh;
}
.header { grid-area: header; }
.sidebar { grid-area: sidebar; }
.main { grid-area: main; }
.aside { grid-area: aside; }
.footer { grid-area: footer; }
복잡한 그리드 아이템 배치를 구현합니다.
/* 12컬럼 그리드 시스템 */
.container {
display: grid;
grid-template-columns: repeat(12, 1fr);
gap: 1rem;
}
/* 그리드 라인으로 배치 */
.item-1 {
grid-column: 1 / 7; /* 1번 라인부터 7번 라인까지 (6컬럼) */
grid-row: 1 / 3; /* 2행 차지 */
}
.item-2 {
grid-column: 7 / -1; /* 7번 라인부터 마지막까지 */
}
/* span 키워드 사용 */
.item-3 {
grid-column: span 4; /* 4컬럼 차지 */
grid-row: span 2; /* 2행 차지 */
}
/* 이름 있는 라인 */
.named-grid {
display: grid;
grid-template-columns:
[sidebar-start] 200px
[sidebar-end main-start] 1fr
[main-end aside-start] 200px
[aside-end];
}
.sidebar { grid-column: sidebar-start / sidebar-end; }
.main { grid-column: main-start / main-end; }
.aside { grid-column: aside-start / aside-end; }
Subgrid를 활용한 카드 정렬입니다.
/* 부모 그리드 */
.card-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
gap: 2rem;
}
/* 자식 그리드 - 부모 그리드 행을 상속 */
.card {
display: grid;
grid-template-rows: subgrid;
grid-row: span 4; /* 4개 행 트랙 차지 */
border: 1px solid #e5e7eb;
border-radius: 8px;
overflow: hidden;
}
.card__image {
/* 첫 번째 행 */
}
.card__title {
/* 두 번째 행 - 모든 카드에서 정렬됨 */
padding: 1rem;
}
.card__description {
/* 세 번째 행 - 모든 카드에서 정렬됨 */
padding: 0 1rem;
}
.card__actions {
/* 네 번째 행 - 모든 카드에서 정렬됨 */
padding: 1rem;
margin-top: auto;
}
<div class="card-grid">
<article class="card">
<img class="card__image" src="1.jpg" alt="">
<h3 class="card__title">짧은 제목</h3>
<p class="card__description">설명 텍스트</p>
<div class="card__actions">
<button>자세히 보기</button>
</div>
</article>
<article class="card">
<img class="card__image" src="2.jpg" alt="">
<h3 class="card__title">이것은 매우 긴 제목이며 여러 줄을 차지합니다</h3>
<p class="card__description">설명 텍스트</p>
<div class="card__actions">
<button>자세히 보기</button>
</div>
</article>
</div>
Subgrid를 활용하면 제목 길이가 다르더라도 모든 카드의 버튼이 같은 높이에 정렬됩니다.
고급 Grid 기법: 매거진 레이아웃입니다.
.magazine-layout {
display: grid;
grid-template-columns: repeat(6, 1fr);
grid-auto-rows: 200px;
gap: 1rem;
}
.article-1 {
grid-column: 1 / 4;
grid-row: 1 / 3;
}
.article-2 {
grid-column: 4 / 7;
grid-row: 1 / 2;
}
.article-3 {
grid-column: 4 / 7;
grid-row: 2 / 3;
}
.article-4 {
grid-column: 1 / 3;
grid-row: 3 / 4;
}
.article-5 {
grid-column: 3 / 5;
grid-row: 3 / 4;
}
.article-6 {
grid-column: 5 / 7;
grid-row: 3 / 4;
}
/* 반응형 조정 */
@media (max-width: 768px) {
.magazine-layout {
grid-template-columns: 1fr;
grid-auto-rows: auto;
}
.article-1,
.article-2,
.article-3,
.article-4,
.article-5,
.article-6 {
grid-column: 1;
grid-row: auto;
}
}
Grid 정렬 속성을 활용합니다.
.grid-container {
display: grid;
grid-template-columns: repeat(3, 200px);
grid-template-rows: repeat(2, 150px);
gap: 1rem;
/* 컨테이너 내 그리드 정렬 */
justify-content: center; /* 수평: start, end, center, space-between, space-around */
align-content: center; /* 수직: start, end, center, space-between, space-around */
/* 아이템 기본 정렬 */
justify-items: stretch; /* 수평: start, end, center, stretch */
align-items: stretch; /* 수직: start, end, center, stretch */
}
/* 개별 아이템 정렬 */
.item-special {
justify-self: center;
align-self: end;
}
활용 팁
- auto-fit vs auto-fill:
auto-fit은 빈 트랙을 축소하고,auto-fill은 빈 트랙을 유지합니다. 반응형 갤러리에는 auto-fit이 적합합니다. - Subgrid 폴백: Subgrid를 지원하지 않는 브라우저를 위해
@supports (grid-template-rows: subgrid)로 분기하세요. - Grid vs Flexbox: 2차원 레이아웃이나 명시적 배치가 필요하면 Grid, 1차원 흐름이나 콘텐츠 크기 기반 배치는 Flexbox를 사용하세요.
- DevTools: Chrome과 Firefox DevTools의 Grid 인스펙터를 활용하면 그리드 라인과 영역을 시각적으로 확인할 수 있습니다.
- minmax():
minmax(200px, 1fr)로 최소/최대 크기를 제한하여 반응형 레이아웃을 쉽게 만드세요.
마무리
CSS Grid는 복잡한 레이아웃을 가장 간결하게 구현하는 도구입니다. Subgrid의 등장으로 중첩된 컴포넌트 정렬 문제가 완전히 해결되었고, auto-fit과 minmax의 조합은 반응형 디자인을 혁신적으로 간소화합니다. Float와 Position 기반 레이아웃은 이제 역사가 되었으며, Grid와 Flexbox가 현대 웹 레이아웃의 양대 축입니다.