이전 포스팅에서 우리는 레이아웃의 구원자 Flexbox에 대해 깊이 열광했습니다. Flexbox는 가로 한 줄(Row) 또는 세로 한 줄(Column)의 요소를 우아하게 정렬하는 데 있어 타의 추종을 불허하는 신적인 존재입니다. 하지만 완벽해 보이는 Flexbox에게도 뼈아픈 한계가 하나 존재합니다. 바로 '1차원(1-Dimensional) 선형 시스템'이라는 족쇄입니다. 갤러리 이미지들이나 복잡한 대시보드 화면처럼 가로와 세로가 동시에 정교하게 딱딱 맞아떨어지는 '바둑판(2차원 면)' 형태의 격자 레이아웃을 짜려고 하면, Flexbox는 갑자기 바보가 됩니다. 가로 한 줄을 맞추고 flex-wrap으로 아래로 떨구면, 떨어진 아랫줄 요소들의 너비가 윗줄 요소들과 미묘하게 틀어지며 오와 열이 박살 나기 일쑤입니다. 이를 해결하기 위해 HTML 구조를 억지로 <div class="row"> 수십 개로 감싸는 등 또다시 HTML을 더럽히는 비극이 발생했습니다. 이 플렉스박스의 1차원적 한계를 완전히 박살 내고, 엑셀 시트처럼 가로축(X)과 세로축(Y)을 동시에 완벽하게 통제하여 2차원 평면의 신(God)으로 군림하기 위해 탄생한 최후의 병기, 그것이 바로 CSS Grid Layout입니다.
이번 12단계 포스팅에서는 Grid의 탄생 철학과 바둑판의 선을 긋는 `grid-template`, 그리고 그리드 레이아웃의 절대 사기 유닛인 `fr(Fraction)` 단위를 통해 완벽히 자세히 알아보겠습니다.

1. 창조의 시작: 바둑판(Grid Container) 생성하기
Flexbox와 마찬가지로, Grid 레이아웃 역시 '부모(Container)'에게 마법을 거는 것부터 시작합니다. 부모 <div>에 display: grid;를 선언하는 순간, 그 내부는 모눈종이를 그릴 수 있는 절대적인 2차원 캔버스로 변모합니다. 하지만 플렉스처럼 display: grid 하나만 썼다고 해서 곧바로 요소들이 바둑판처럼 예쁘게 배열되지는 않습니다. 브라우저는 아직 당신이 모눈종이의 '칸(Track)'을 어떻게, 몇 개로 나눌지 명령받지 못했기 때문입니다.
2. 모눈종이 줄 긋기: grid-template-columns / rows
우리는 부모 컨테이너에게 아주 명확하게 명령해야 합니다. "세로줄(기둥)은 몇 개 세울 건지, 가로줄(행)은 몇 개 칠 건지, 그리고 각각의 칸 크기는 몇 픽셀로 할 건지"를 말입니다.
.grid-container {
display: grid;
/* 세로 기둥(Column)을 3개 세우겠다. 첫 번째는 200px, 두 번째는 300px, 세 번째는 200px */
grid-template-columns: 200px 300px 200px;
/* 가로 행(Row)을 2개 치겠다. 첫 번째 줄은 높이 150px, 두 번째 줄은 높이 100px */
grid-template-rows: 150px 100px;
}
위 코드를 작성하는 순간, 부모 박스 안에는 총 6개(3열 x 2행)의 완벽한 엑셀 셀(Cell) 모양의 모눈종이가 그려집니다. 그리고 HTML상에 존재하는 직계 자식 요소들은 1번 칸부터 시작하여 차례대로 쏙쏙 자기 자리를 찾아 자동으로 꽂혀 들어갑니다. 만약 자식이 7개라면? 6번 칸까지 다 차고 남은 7번째 녀석은 자동으로 브라우저가 몰래 새로운 행(암시적 그리드, Implicit Grid)을 몰래 추가하여 밑으로 떨어뜨려 줍니다.

3. 그리드의 궁극기: 절대 사기 유닛 'fr' (Fraction)
과거 웹 개발자들은 화면을 3등분하기 위해 width: 33.3333%;라는 추악하고 눈물겨운 코드를 써야 했습니다. 게다가 중간에 여백(Gap)이라도 20px씩 끼워 넣는 날에는, 전체 100%에서 40px을 빼고 그걸 다시 3으로 나누는 수학적 대혼란을 겪어야 했습니다. W3C는 이 고통을 끝내기 위해 Grid와 함께 fr (Fraction, 분수/비율)이라는 기적의 단위를 탄생시켰습니다.
fr은 "화면에 남은 잉여 텅 빈 공간을 내가 제시한 비율만큼 공평하게 쪼개서 차지하겠다"라는 뜻입니다. (Flexbox의 flex-grow와 매우 흡사하지만 훨씬 강력합니다.)
.grid-container {
display: grid;
/* 남은 공간을 1대 2대 1의 비율로 3조각 내어 차지하라! 퍼센트 계산 따위 필요 없다! */
grid-template-columns: 1fr 2fr 1fr;
/* 팁: 고정된 메뉴바 250px을 빼고, 남은 공간을 혼자 다 먹어라(1fr) */
grid-template-columns: 250px 1fr;
}

fr 단위를 사용하면 모니터가 커지든 스마트폰으로 좁아지든 브라우저 엔진이 알아서 정확한 픽셀을 백그라운드에서 계산하여 1:2:1의 비율을 완벽하게 칼같이 유지해 줍니다. calc() 함수나 % 노가다가 프론트엔드 역사에서 완전히 사라지는 순간입니다.
4. 여백의 미학을 한 줄로: gap (그리드 간격)
박스 3개를 가로로 놨을 때, 박스 사이사이에만 20px의 간격을 띄우려면 옛날에는 어떻게 했을까요? margin-right: 20px;을 준 다음, :last-child로 마지막 요소만 마진을 0으로 강제로 빼주는 지저분한 코드를 덕지덕지 발라야 했습니다. Grid에서는 그런 야만적인 짓을 할 필요가 없습니다. 부모 컨테이너에 gap: 20px; (구 grid-gap) 단 한 줄만 선언해 주면, 브라우저가 바둑판의 '선(Line)' 사이에만 아주 깔끔하게 20px 두께의 벽돌(여백)을 발라줍니다. 가장자리 벽(테두리)에는 마진이 생기지 않고, 오직 아이템 '사이사이'에만 여백이 들어가는 완벽한 건축 설계입니다. (row-gap과 column-gap으로 가로세로 여백을 다르게 줄 수도 있습니다.)
5. 반복되는 노가다의 종식: repeat() 함수
쇼핑몰 상품 리스트처럼 똑같은 크기의 1fr짜리 기둥(Column)을 12개 만들어야 한다면 어떻게 코드를 짤까요? grid-template-columns: 1fr 1fr 1fr 1fr 1fr 1fr 1fr 1fr 1fr 1fr 1fr 1fr; 이렇게 치다가는 손가락에 관절염이 올 것입니다. CSS Grid는 프로그래밍 언어의 for 반복문과 같은 repeat() 함수를 내장하고 있습니다.
.grid-container {
/* 1fr짜리 열을 12번 반복해서 생성해라! */
grid-template-columns: repeat(12, 1fr);
}
정리하며
이번 12단계 포스팅에서는 가로세로 2차원 엑셀 시트 뺨치는 완벽한 모눈종이를 창조하는 CSS Grid의 기초 '선 긋기(Template)'와, 비율을 지배하는 기적의 단위 fr에 대해 깊이 파고들었습니다. 자, 이제 부모가 모눈종이 칸은 완벽하게 다 짜놓았습니다. 자식들은 기본적으로 1번 칸, 2번 칸에 얌전히 한 칸씩 들어갑니다. 그런데 한 녀석이 갑자기 "나는 메인 주인공이니까 1번 칸부터 3번 칸까지 가로로 쫙 합쳐서(병합) 커다란 대문짝만 한 자리를 차지하고 싶어!"라고 엑셀의 '셀 병합' 같은 요구를 해옵니다. 어떻게 이 자식 요소를 이웃집 칸까지 확장하여 배치할 수 있을까요? 격자의 선(Line) 넘버를 세는 기묘한 기법! 다음 13단계 포스팅에서는 "CSS Grid (2편: 심화) - Grid Line을 이용한 자유자재 셀 병합과 auto-fit의 기적"에 대해 상세히 자세히 알아보겠습니다.
'StyleSheet > CSS' 카테고리의 다른 글
| [CSS] CSS 기초와 핵심 개념 완벽 가이드 (0) | 2026.08.10 |
|---|---|
| [CSS] 실무에서 자주 쓰이는 Flexbox UI 패턴 5가지 완벽 정복 (0) | 2026.07.28 |
| [CSS] Flexbox (2편: Item)(Grow, Shrink) (0) | 2026.07.28 |
| [CSS] Flexbox 컨테이너 속성 (0) | 2026.07.28 |
| [CSS] Flexbox (1편: Container) (0) | 2026.07.28 |