CSS Grid는 CSS에 추가된 가장 강력한 레이아웃 시스템입니다. 2026년에 Subgrid 등 Grid Level 2 기능이 모든 주요 브라우저에서 완전히 지원됩니다.
Grid 기본: 열, 행, 배치
Grid는 2차원 좌표 시스템을 생성합니다.
/* CSS Grid fundamentals */
.grid-container {
display: grid;
/* Define columns */
grid-template-columns: 200px 1fr 1fr; /* fixed + flexible */
grid-template-columns: repeat(3, 1fr); /* 3 equal columns */
grid-template-columns: repeat(auto-fill, minmax(200px, 1fr)); /* responsive */
/* Define rows */
grid-template-rows: auto 1fr auto; /* header, content, footer */
/* Gaps */
gap: 1rem; /* both row and column gap */
row-gap: 0.5rem;
column-gap: 1.5rem;
/* Alignment */
justify-items: stretch; /* horizontal alignment of cells */
align-items: start; /* vertical alignment of cells */
justify-content: center; /* horizontal alignment of the grid */
align-content: center; /* vertical alignment of the grid */
}
/* Place items */
.item {
grid-column: 1 / 3; /* span from column 1 to 3 */
grid-row: 1 / 2;
grid-column: span 2; /* span 2 columns */
grid-area: 1 / 1 / 3 / 3; /* row-start / col-start / row-end / col-end */
}grid-template-areas: 시각적 레이아웃 정의
grid-template-areas를 사용하여 ASCII로 레이아웃을 시각적으로 정의할 수 있습니다.
/* grid-template-areas: name regions visually */
.page-layout {
display: grid;
grid-template-areas:
"header header header"
"sidebar main main"
"sidebar aside aside"
"footer footer footer";
grid-template-columns: 250px 1fr 300px;
grid-template-rows: 60px 1fr auto 80px;
min-height: 100vh;
gap: 1rem;
}
.header { grid-area: header; }
.sidebar { grid-area: sidebar; }
.main { grid-area: main; }
.aside { grid-area: aside; }
.footer { grid-area: footer; }
/* Responsive: stack on mobile */
@media (max-width: 768px) {
.page-layout {
grid-template-areas:
"header"
"main"
"aside"
"sidebar"
"footer";
grid-template-columns: 1fr;
grid-template-rows: auto;
}
}auto-fill vs auto-fit: 미디어 쿼리 없는 반응형
minmax()와 함께 auto-fill과 auto-fit을 사용하면 미디어 쿼리 없이 반응형 그리드를 만들 수 있습니다.
/* auto-fill vs auto-fit — the most important Grid distinction */
/* auto-fill: creates as many columns as possible, even if empty */
.gallery-fill {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
gap: 1rem;
}
/* Result: always fills the row with tracks, even with empty ones */
/* auto-fit: collapses empty tracks, stretches filled items */
.gallery-fit {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
gap: 1rem;
}
/* Result: items expand to fill available space */
/* Practical: responsive card grid (no media queries!) */
.card-grid {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(min(300px, 100%), 1fr));
gap: 1.5rem;
}
/* min(300px, 100%) prevents overflow on very small screens */minmax()와 내재적 크기 조정
minmax(min, max)는 그리드 트랙의 최소 및 최대 크기를 설정합니다.
/* minmax() — set minimum and maximum track size */
/* Card layout: minimum 250px, maximum 1fr */
.cards {
display: grid;
grid-template-columns: repeat(3, minmax(250px, 1fr));
}
/* Intrinsic sizing with min-content / max-content */
.table-grid {
display: grid;
grid-template-columns: max-content 1fr max-content;
/* First and last columns size to content, middle fills rest */
}
/* fit-content() — like minmax(auto, max-content) but capped */
.nav {
display: grid;
grid-template-columns: fit-content(200px) 1fr fit-content(200px);
}
/* Dense packing: fill holes left by spanning items */
.masonry-like {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(150px, 1fr));
grid-auto-rows: 150px;
grid-auto-flow: dense; /* fills gaps automatically */
}
.tall-item {
grid-row: span 2; /* takes 2 rows */
}
.wide-item {
grid-column: span 2; /* takes 2 columns */
}Subgrid: CSS Grid Level 2 (2026)
Subgrid는 중첩된 그리드가 부모 그리드의 트랙 정의에 참여할 수 있게 합니다.
/* Subgrid — CSS Grid Level 2, fully supported in 2026 */
/* Allows nested grids to align to parent grid lines */
/* The problem subgrid solves: */
.card-container {
display: grid;
grid-template-columns: repeat(3, 1fr);
gap: 1rem;
}
/* Without subgrid: each card's internal layout is independent */
/* Card titles and content don't align across cards */
/* With subgrid: */
.card {
display: grid;
grid-row: span 3; /* card spans 3 implicit rows */
grid-template-rows: subgrid; /* inherits parent row tracks */
}
/* Now all cards share the same row grid — titles align! */
.card .card-header { grid-row: 1; }
.card .card-body { grid-row: 2; }
.card .card-footer { grid-row: 3; }
/* Subgrid for columns too */
.sidebar-layout {
display: grid;
grid-template-columns: 1fr 3fr;
}
.main-content {
display: grid;
grid-column: 2;
grid-template-columns: subgrid; /* aligns to parent columns */
}
/* Browser support: Chrome 117+, Firefox 71+, Safari 16+ — all major browsers */Grid 애니메이션과 트랜지션
최신 브라우저는 grid-template-columns와 grid-template-rows의 트랜지션을 지원합니다.
/* Grid transitions and animation */
/* Animate grid column width on hover */
.sidebar-layout {
display: grid;
grid-template-columns: 250px 1fr;
transition: grid-template-columns 0.3s ease;
}
.sidebar-layout:has(.sidebar:hover) {
grid-template-columns: 350px 1fr; /* expand on hover */
}
/* CSS-only accordion with Grid */
.accordion-item {
display: grid;
grid-template-rows: auto 0fr; /* collapsed: 0 fraction */
transition: grid-template-rows 0.3s ease;
overflow: hidden;
}
.accordion-item.open {
grid-template-rows: auto 1fr; /* expanded: 1 fraction */
}
.accordion-content {
min-height: 0; /* required for 0fr to work */
}CSS Grid vs Flexbox: 언제 무엇을 사용할까
| Scenario | CSS Grid | Flexbox |
|---|---|---|
| Page layout (header/footer/sidebar) | Perfect | Awkward |
| Navigation bar items | Works | Perfect |
| Card grid (equal columns) | Perfect | Needs JS for equal height |
| Centering content | Easy (place-items) | Easy (align/justify) |
| Vertical list of items | Works | Perfect |
| Complex form layout | Perfect | Complex |
| Responsive without breakpoints | auto-fill/fit | Limited |
모범 사례
- 페이지 레이아웃에는 Grid, 컴포넌트에는 Flexbox를 사용하세요.
- 반응형 카드 그리드에는 repeat(auto-fill, minmax())를 선호하세요.
- 복잡한 레이아웃에는 grid-template-areas로 영역에 이름을 붙이세요.
- 별도의 그리드 항목 내 콘텐츠 정렬에는 Subgrid를 사용하세요.
- 그리드 간격에는 margin 대신 gap을 사용하세요.
자주 묻는 질문
Grid와 Flexbox 중 언제 무엇을 사용해야 하나요?
CSS Grid는 행과 열을 모두 제어하는 2차원 레이아웃에 뛰어납니다. Flexbox는 1차원 레이아웃에 더 적합합니다.
grid-template-columns와 grid-auto-columns의 차이는?
grid-template-columns는 명시적 열을 정의하고, grid-auto-columns는 암묵적으로 생성된 열의 크기를 설정합니다.
Subgrid와 중첩 그리드의 차이는?
Subgrid는 부모의 트랙 정의를 상속하여 자식 항목이 부모 그리드 선에 정렬됩니다.
grid-auto-flow: dense는 무엇인가요?
순서를 건너뛴 항목이 남긴 구멍을 채우려고 시도합니다.
Grid와 Flexbox를 혼합할 수 있나요?
물론입니다. 둘은 다른 레벨에서 작동하며 서로 보완합니다.