[CSS] 2차원 레이아웃의 끝판왕, CSS Grid 완벽 가이드

Flexbox는 컴포넌트 내부의 아이템을 정렬하는 데 매우 뛰어나지만, 웹 페이지 전체의 복잡한 구조를 잡기에는 때로 한계가 있습니다.

바로 이 지점에서 CSS Grid가 등장합니다. Grid는 이름 그대로 페이지를 **행(row)과 열(column)으로 이루어진 격자(Grid)**로 나누어, 마치 엑셀 시트나 신문처럼 요소를 원하는 칸에 정확하게 배치할 수 있는 2차원 레이아웃 시스템입니다. Flexbox가 1차선 도로라면, Grid는 바둑판과 같습니다.

1. Grid vs Flexbox: 언제 무엇을 써야 할까?

초보자들이 가장 많이 헷갈리는 부분입니다. 둘은 경쟁 관계가 아니라, 각자의 역할이 다른 강력한 동료입니다.

  • Flexbox (1차원, Content-first):
    • 하나의 행이나 열 안에서 아이템들을 정렬할 때 사용합니다.
    • 내비게이션 메뉴, 버튼 그룹, 카드 목록 등 컴포넌트 단위의 레이아웃에 최적화되어 있습니다.
    • 콘텐츠의 양에 따라 배치가 유연하게 결정됩니다.
  • Grid (2차원, Layout-first):
    • 행과 열을 동시에 사용하여 전체 페이지의 구조를 짤 때 사용합니다.
    • 전체 페이지 레이아웃, 대시보드, 복잡한 형태의 UI 등 거시적인 구조 설계에 최적화되어 있습니다.
    • 먼저 레이아웃(격자)을 정의하고 그 안에 콘텐츠를 배치합니다.

핵심 팁: Grid로 전체적인 ‘뼈대’를 만들고, 그 뼈대 안의 컴포넌트들은 Flexbox로 정렬하는 것이 가장 이상적인 조합입니다.

2. Grid 시작하기: 컨테이너 기본 속성

Grid 역시 Flexbox처럼 컨테이너(부모)와 아이템(자식) 구조를 가집니다. 시작은 부모 요소에 display: grid;를 선언하는 것입니다.

<div class="grid-container">
  <div class="grid-item">1</div>
  <div class="grid-item">2</div>
  <div class="grid-item">3</div>
  ...
</div>

◼️ display: grid;

  • 해당 요소를 Grid 컨테이너로 만듭니다. 이것만으로는 시각적 변화가 거의 없습니다. 격자의 형태를 직접 정의해주어야 합니다.

◼️ grid-template-columns & grid-template-rows

  • Grid의 핵심 속성입니다. 열과 행의 크기와 개수를 정의합니다.
  • fr (fractional unit) 단위를 사용하면 비율에 따라 유연하게 공간을 나눌 수 있습니다.
.grid-container {
  display: grid;
  /* 3개의 열(column)을 만듭니다. */
  /* 1fr 1fr 1fr 은 '같은 비율로 3등분' 이라는 의미입니다. */
  grid-template-columns: 1fr 1fr 1fr;
  
  /* 2개의 행(row)을 만듭니다. 첫 행은 100px, 두번째는 200px 높이. */
  grid-template-rows: 100px 200px;
}

/* repeat() 함수로 더 간결하게 표현할 수 있습니다. */
.grid-container {
  grid-template-columns: repeat(3, 1fr); /* 1fr 1fr 1fr 과 동일 */
}

◼️ gap (구 grid-gap)

  • 아이템들 사이의 간격(Gutter)을 설정합니다. margin을 일일이 계산할 필요가 없어 매우 편리합니다.
.grid-container {
  /* 행과 열의 간격을 모두 20px로 설정 */
  gap: 20px;

  /* 행 간격은 10px, 열 간격은 20px로 따로 설정할 수도 있습니다. */
  /* row-gap: 10px; */
  /* column-gap: 20px; */
}

3. Grid 아이템 배치하기: grid-column & grid-row

Grid는 격자를 만들 때 눈에 보이지 않는 번호가 매겨진 **라인(Line)**을 생성합니다. 3개의 열을 만들었다면, 수직 라인은 1번부터 4번까지 생깁니다. 우리는 이 라인 번호를 이용해 아이템을 원하는 위치에 배치하고 크기를 조절할 수 있습니다.

  • grid-column-start, grid-column-end: 아이템이 시작하고 끝날 열(column) 라인을 지정합니다.
  • grid-row-start, grid-row-end: 아이템이 시작하고 끝날 행(row) 라인을 지정합니다.
  • grid-column, grid-row: 위 속성들의 단축 속성입니다. (start / end)
.item-header {
  /* 1번 열 라인에서 시작해서 4번 열 라인에서 끝남 (3칸 모두 차지) */
  grid-column: 1 / 4; 
}

.item-sidebar {
  /* 1번 열 라인에서 2번 열 라인까지 (첫 번째 칸) */
  grid-column: 1 / 2;
  /* 2번 행 라인에서 4번 행 라인까지 (세로로 2칸 차지) */
  grid-row: 2 / 4;
}

.item-main {
  /* 2번 열 라인에서 4번 열 라인까지 (오른쪽 2칸 차지) */
  grid-column: 2 / 4;
}

요약 및 정리

CSS Grid는 복잡한 2차원 레이아웃을 직관적이고 견고하게 만들 수 있는 강력한 도구입니다.

  1. Grid는 행과 열, 2차원 레이아웃을 위한 시스템이며, Flexbox는 1차원 정렬을 위한 시스템입니다.
  2. display: grid로 시작하며, grid-template-columnsgrid-template-rows로 격자의 구조를 정의하는 것이 핵심입니다.
  3. gap 속성으로 아이템 사이의 간격을 손쉽게 제어할 수 있습니다.
  4. 아이템은 grid-columngrid-row 속성을 사용하여 격자 라인에 맞춰 원하는 위치와 크기로 배치할 수 있습니다.

Flexbox와 Grid는 웹 레이아웃을 위한 현대 CSS의 양대 산맥입니다. 이 두 가지를 자유자재로 조합해서 사용할 수 있다면, 상상하는 거의 모든 웹 레이아웃을 구현할 수 있게 될 것입니다.